Move kwin themes to a separate package
This commit is contained in:
parent
913168e7fb
commit
4827a44c35
@ -1,14 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.0)
|
|
||||||
|
|
||||||
include(GenerateExportHeader)
|
|
||||||
|
|
||||||
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
|
|
||||||
|
|
||||||
include(KDEInstallDirs)
|
|
||||||
include(KDECMakeSettings)
|
|
||||||
|
|
||||||
find_package(KDecoration2 REQUIRED)
|
|
||||||
|
|
||||||
add_subdirectory(kdecoration)
|
|
||||||
add_subdirectory(libbreezecommon)
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
.PHONY: build clean install
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf build
|
|
||||||
|
|
||||||
build:
|
|
||||||
cmake -B build
|
|
||||||
cmake --build build
|
|
||||||
|
|
||||||
install:
|
|
||||||
DESTDIR=$(DESTDIR) cmake --install build
|
|
||||||
|
|
||||||
include ../Makefile.inc
|
|
||||||
@ -1,96 +0,0 @@
|
|||||||
add_definitions(-DTRANSLATION_DOMAIN="breeze_kwin_deco")
|
|
||||||
|
|
||||||
find_package(KF5 REQUIRED COMPONENTS CoreAddons GuiAddons ConfigWidgets WindowSystem I18n IconThemes)
|
|
||||||
find_package(Qt5 CONFIG REQUIRED COMPONENTS DBus)
|
|
||||||
|
|
||||||
### XCB
|
|
||||||
find_package(XCB COMPONENTS XCB)
|
|
||||||
set_package_properties(XCB PROPERTIES
|
|
||||||
DESCRIPTION "X protocol C-language Binding"
|
|
||||||
URL "https://xcb.freedesktop.org"
|
|
||||||
TYPE OPTIONAL
|
|
||||||
PURPOSE "Required to pass style properties to native Windows on X11 Platform"
|
|
||||||
)
|
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
|
||||||
|
|
||||||
set(BREEZE_HAVE_X11 ${XCB_XCB_FOUND})
|
|
||||||
if (XCB_XCB_FOUND)
|
|
||||||
find_package(Qt5 REQUIRED CONFIG COMPONENTS X11Extras)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
else()
|
|
||||||
|
|
||||||
set(BREEZE_HAVE_X11 FALSE)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
################# configuration #################
|
|
||||||
configure_file(config-breeze.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-breeze.h )
|
|
||||||
|
|
||||||
################# includes #################
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/libbreezecommon)
|
|
||||||
include_directories(${CMAKE_BINARY_DIR}/libbreezecommon)
|
|
||||||
|
|
||||||
################# newt target #################
|
|
||||||
### plugin classes
|
|
||||||
set(breezedecoration_SRCS
|
|
||||||
breezebutton.cpp
|
|
||||||
../libbreezecommon/breezeboxshadowrenderer.cpp
|
|
||||||
breezedecoration.cpp
|
|
||||||
breezeexceptionlist.cpp
|
|
||||||
breezesettingsprovider.cpp
|
|
||||||
breezesizegrip.cpp)
|
|
||||||
|
|
||||||
kconfig_add_kcfg_files(breezedecoration_SRCS breezesettings.kcfgc)
|
|
||||||
|
|
||||||
### config classes
|
|
||||||
### they are kept separately because they might move in a separate library in the future
|
|
||||||
set(breezedecoration_config_SRCS
|
|
||||||
config/breezeconfigwidget.cpp
|
|
||||||
config/breezedetectwidget.cpp
|
|
||||||
config/breezeexceptiondialog.cpp
|
|
||||||
config/breezeexceptionlistwidget.cpp
|
|
||||||
config/breezeexceptionmodel.cpp
|
|
||||||
config/breezeitemmodel.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(breezedecoration_config_PART_FORMS
|
|
||||||
config/ui/breezeconfigurationui.ui
|
|
||||||
config/ui/breezedetectwidget.ui
|
|
||||||
config/ui/breezeexceptiondialog.ui
|
|
||||||
config/ui/breezeexceptionlistwidget.ui
|
|
||||||
)
|
|
||||||
|
|
||||||
ki18n_wrap_ui(breezedecoration_config_PART_FORMS_HEADERS ${breezedecoration_config_PART_FORMS})
|
|
||||||
|
|
||||||
### build library
|
|
||||||
add_library(kali-breezedecoration MODULE
|
|
||||||
${breezedecoration_SRCS}
|
|
||||||
${breezedecoration_config_SRCS}
|
|
||||||
${breezedecoration_config_PART_FORMS_HEADERS})
|
|
||||||
|
|
||||||
target_link_libraries(kali-breezedecoration
|
|
||||||
PUBLIC
|
|
||||||
Qt5::Core
|
|
||||||
Qt5::Gui
|
|
||||||
Qt5::DBus
|
|
||||||
PRIVATE
|
|
||||||
KDecoration2::KDecoration
|
|
||||||
KF5::ConfigCore
|
|
||||||
KF5::CoreAddons
|
|
||||||
KF5::ConfigWidgets
|
|
||||||
KF5::GuiAddons
|
|
||||||
KF5::I18n
|
|
||||||
KF5::IconThemes
|
|
||||||
KF5::WindowSystem)
|
|
||||||
|
|
||||||
if(BREEZE_HAVE_X11)
|
|
||||||
target_link_libraries(kali-breezedecoration
|
|
||||||
PUBLIC
|
|
||||||
Qt5::X11Extras
|
|
||||||
XCB::XCB)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
install(TARGETS kali-breezedecoration DESTINATION ${PLUGIN_INSTALL_DIR}/org.kde.kdecoration2)
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
#!bin/sh
|
|
||||||
$EXTRACTRC `find . -name \*.rc -o -name \*.ui -o -name \*.kcfg` >> rc.cpp
|
|
||||||
$XGETTEXT `find . -name \*.cc -o -name \*.cpp -o -name \*.h` -o $podir/breeze_kwin_deco.pot
|
|
||||||
rm -f rc.cpp
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
#ifndef breeze_h
|
|
||||||
#define breeze_h
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "breezesettings.h"
|
|
||||||
|
|
||||||
#include <QSharedPointer>
|
|
||||||
#include <QList>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
//* convenience typedefs
|
|
||||||
using InternalSettingsPtr = QSharedPointer<InternalSettings>;
|
|
||||||
using InternalSettingsList = QList<InternalSettingsPtr>;
|
|
||||||
using InternalSettingsListIterator = QListIterator<InternalSettingsPtr>;
|
|
||||||
|
|
||||||
//* metrics
|
|
||||||
enum Metrics
|
|
||||||
{
|
|
||||||
|
|
||||||
//* corner radius (pixels)
|
|
||||||
Frame_FrameRadius = 4,
|
|
||||||
|
|
||||||
//* titlebar metrics, in units of small spacing
|
|
||||||
TitleBar_TopMargin = 3,
|
|
||||||
TitleBar_BottomMargin = 3,
|
|
||||||
TitleBar_SideMargin = 1,
|
|
||||||
TitleBar_ButtonSpacing = 2,
|
|
||||||
|
|
||||||
Frame_BorderSize = 2,
|
|
||||||
|
|
||||||
// shadow dimensions (pixels)
|
|
||||||
Shadow_Overlap = 3,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
//* standard pen widths
|
|
||||||
namespace PenWidth
|
|
||||||
{
|
|
||||||
/* Using 1 instead of slightly more than 1 causes symbols drawn with
|
|
||||||
* pen strokes to look skewed. The exact amount added does not matter
|
|
||||||
* as long as it isn't too visible.
|
|
||||||
*/
|
|
||||||
// The standard pen stroke width for symbols.
|
|
||||||
static constexpr qreal Symbol = 1.01;
|
|
||||||
}
|
|
||||||
|
|
||||||
//* exception
|
|
||||||
enum ExceptionMask
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
BorderSize = 1<<4
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"KPlugin": {
|
|
||||||
"Description": "Window decoration using Kali's visual style for the Plasma Desktop",
|
|
||||||
"EnabledByDefault": true,
|
|
||||||
"Id": "org.kali.kali",
|
|
||||||
"Name": "Kali",
|
|
||||||
"ServiceTypes": [
|
|
||||||
"org.kde.kdecoration2"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"org.kde.kdecoration2": {
|
|
||||||
"blur": false,
|
|
||||||
"kcmodule": true,
|
|
||||||
"recommendedBorderSize": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,471 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
|
|
||||||
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
#include "breezebutton.h"
|
|
||||||
|
|
||||||
#include <KDecoration2/DecoratedClient>
|
|
||||||
#include <KColorUtils>
|
|
||||||
#include <KIconLoader>
|
|
||||||
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QVariantAnimation>
|
|
||||||
#include <QPainterPath>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
using KDecoration2::ColorRole;
|
|
||||||
using KDecoration2::ColorGroup;
|
|
||||||
using KDecoration2::DecorationButtonType;
|
|
||||||
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
Button::Button(DecorationButtonType type, Decoration* decoration, QObject* parent)
|
|
||||||
: DecorationButton(type, decoration, parent)
|
|
||||||
, m_animation( new QVariantAnimation( this ) )
|
|
||||||
{
|
|
||||||
|
|
||||||
// setup animation
|
|
||||||
// It is important start and end value are of the same type, hence 0.0 and not just 0
|
|
||||||
m_animation->setStartValue( 0.0 );
|
|
||||||
m_animation->setEndValue( 1.0 );
|
|
||||||
m_animation->setEasingCurve( QEasingCurve::InOutQuad );
|
|
||||||
connect(m_animation, &QVariantAnimation::valueChanged, this, [this](const QVariant &value) {
|
|
||||||
setOpacity(value.toReal());
|
|
||||||
});
|
|
||||||
|
|
||||||
// setup default geometry
|
|
||||||
const int height = decoration->buttonHeight();
|
|
||||||
setGeometry(QRect(0, 0, height, height));
|
|
||||||
setIconSize(QSize( height, height ));
|
|
||||||
|
|
||||||
// connections
|
|
||||||
connect(decoration->client().data(), SIGNAL(iconChanged(QIcon)), this, SLOT(update()));
|
|
||||||
connect(decoration->settings().data(), &KDecoration2::DecorationSettings::reconfigured, this, &Button::reconfigure);
|
|
||||||
connect( this, &KDecoration2::DecorationButton::hoveredChanged, this, &Button::updateAnimationState );
|
|
||||||
|
|
||||||
reconfigure();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
Button::Button(QObject *parent, const QVariantList &args)
|
|
||||||
: Button(args.at(0).value<DecorationButtonType>(), args.at(1).value<Decoration*>(), parent)
|
|
||||||
{
|
|
||||||
m_flag = FlagStandalone;
|
|
||||||
//! icon size must return to !valid because it was altered from the default constructor,
|
|
||||||
//! in Standalone mode the button is not using the decoration metrics but its geometry
|
|
||||||
m_iconSize = QSize(-1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
Button *Button::create(DecorationButtonType type, KDecoration2::Decoration *decoration, QObject *parent)
|
|
||||||
{
|
|
||||||
if (auto d = qobject_cast<Decoration*>(decoration))
|
|
||||||
{
|
|
||||||
Button *b = new Button(type, d, parent);
|
|
||||||
switch( type )
|
|
||||||
{
|
|
||||||
|
|
||||||
case DecorationButtonType::Close:
|
|
||||||
b->setVisible( d->client().data()->isCloseable() );
|
|
||||||
QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::closeableChanged, b, &Breeze::Button::setVisible );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DecorationButtonType::Maximize:
|
|
||||||
b->setVisible( d->client().data()->isMaximizeable() );
|
|
||||||
QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::maximizeableChanged, b, &Breeze::Button::setVisible );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DecorationButtonType::Minimize:
|
|
||||||
b->setVisible( d->client().data()->isMinimizeable() );
|
|
||||||
QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::minimizeableChanged, b, &Breeze::Button::setVisible );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DecorationButtonType::ContextHelp:
|
|
||||||
b->setVisible( d->client().data()->providesContextHelp() );
|
|
||||||
QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::providesContextHelpChanged, b, &Breeze::Button::setVisible );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DecorationButtonType::Shade:
|
|
||||||
b->setVisible( d->client().data()->isShadeable() );
|
|
||||||
QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::shadeableChanged, b, &Breeze::Button::setVisible );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DecorationButtonType::Menu:
|
|
||||||
QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::iconChanged, b, [b]() { b->update(); });
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
void Button::paint(QPainter *painter, const QRect &repaintRegion)
|
|
||||||
{
|
|
||||||
Q_UNUSED(repaintRegion)
|
|
||||||
|
|
||||||
if (!decoration()) return;
|
|
||||||
|
|
||||||
painter->save();
|
|
||||||
|
|
||||||
// translate from offset
|
|
||||||
if( m_flag == FlagFirstInList ) painter->translate( m_offset );
|
|
||||||
else painter->translate( 0, m_offset.y() );
|
|
||||||
|
|
||||||
if( !m_iconSize.isValid() ) m_iconSize = geometry().size().toSize();
|
|
||||||
|
|
||||||
// menu button
|
|
||||||
if (type() == DecorationButtonType::Menu)
|
|
||||||
{
|
|
||||||
|
|
||||||
const QRectF iconRect( geometry().topLeft(), m_iconSize );
|
|
||||||
if (auto deco = qobject_cast<Decoration*>(decoration())) {
|
|
||||||
const QPalette activePalette = KIconLoader::global()->customPalette();
|
|
||||||
QPalette palette = decoration()->client().data()->palette();
|
|
||||||
palette.setColor(QPalette::Foreground, deco->fontColor());
|
|
||||||
KIconLoader::global()->setCustomPalette(palette);
|
|
||||||
decoration()->client().data()->icon().paint(painter, iconRect.toRect());
|
|
||||||
if (activePalette == QPalette()) {
|
|
||||||
KIconLoader::global()->resetPalette();
|
|
||||||
} else {
|
|
||||||
KIconLoader::global()->setCustomPalette(palette);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
decoration()->client().data()->icon().paint(painter, iconRect.toRect());
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
drawIcon( painter );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
painter->restore();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
void Button::drawIcon( QPainter *painter ) const
|
|
||||||
{
|
|
||||||
|
|
||||||
painter->setRenderHints( QPainter::Antialiasing );
|
|
||||||
|
|
||||||
/*
|
|
||||||
scale painter so that its window matches QRect( -1, -1, 20, 20 )
|
|
||||||
this makes all further rendering and scaling simpler
|
|
||||||
all further rendering is preformed inside QRect( 0, 0, 18, 18 )
|
|
||||||
*/
|
|
||||||
painter->translate( geometry().topLeft() );
|
|
||||||
|
|
||||||
const qreal width( m_iconSize.width() );
|
|
||||||
painter->scale( width/20, width/20 );
|
|
||||||
painter->translate( 1, 1 );
|
|
||||||
|
|
||||||
// render background
|
|
||||||
const QColor backgroundColor( this->backgroundColor() );
|
|
||||||
if( backgroundColor.isValid() )
|
|
||||||
{
|
|
||||||
painter->setPen( Qt::NoPen );
|
|
||||||
painter->setBrush( backgroundColor );
|
|
||||||
painter->drawEllipse( QRectF( 0, 0, 18, 18 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// render mark
|
|
||||||
const QColor foregroundColor( this->foregroundColor() );
|
|
||||||
if( foregroundColor.isValid() )
|
|
||||||
{
|
|
||||||
|
|
||||||
// setup painter
|
|
||||||
QPen pen( foregroundColor );
|
|
||||||
pen.setCapStyle( Qt::RoundCap );
|
|
||||||
pen.setJoinStyle( Qt::MiterJoin );
|
|
||||||
pen.setWidthF( PenWidth::Symbol*qMax((qreal)2.0, 20/width ) );
|
|
||||||
|
|
||||||
painter->setPen( pen );
|
|
||||||
painter->setBrush( Qt::NoBrush );
|
|
||||||
|
|
||||||
switch( type() )
|
|
||||||
{
|
|
||||||
|
|
||||||
case DecorationButtonType::Close:
|
|
||||||
{
|
|
||||||
painter->drawLine( QPointF( 6, 6 ), QPointF( 12, 12 ) );
|
|
||||||
painter->drawLine( QPointF( 6, 12 ), QPointF( 12, 6 ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DecorationButtonType::Maximize:
|
|
||||||
{
|
|
||||||
pen.setJoinStyle( Qt::RoundJoin );
|
|
||||||
painter->setPen( pen );
|
|
||||||
|
|
||||||
painter->drawPolygon( QVector<QPointF>{
|
|
||||||
QPointF( 6, 6 ),
|
|
||||||
QPointF( 6, 12 ),
|
|
||||||
QPointF( 12, 12 ),
|
|
||||||
QPointF( 12, 6 )} );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DecorationButtonType::Minimize:
|
|
||||||
{
|
|
||||||
painter->drawLine( QPointF( 6, 12 ), QPointF( 12, 12 ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DecorationButtonType::OnAllDesktops:
|
|
||||||
{
|
|
||||||
painter->setPen( Qt::NoPen );
|
|
||||||
painter->setBrush( foregroundColor );
|
|
||||||
|
|
||||||
if( isChecked())
|
|
||||||
{
|
|
||||||
|
|
||||||
// outer ring
|
|
||||||
painter->drawEllipse( QRectF( 3, 3, 12, 12 ) );
|
|
||||||
|
|
||||||
// center dot
|
|
||||||
QColor backgroundColor( this->backgroundColor() );
|
|
||||||
auto d = qobject_cast<Decoration*>( decoration() );
|
|
||||||
if( !backgroundColor.isValid() && d ) backgroundColor = d->titleBarColor();
|
|
||||||
|
|
||||||
if( backgroundColor.isValid() )
|
|
||||||
{
|
|
||||||
painter->setBrush( backgroundColor );
|
|
||||||
painter->drawEllipse( QRectF( 8, 8, 2, 2 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
painter->drawPolygon( QVector<QPointF> {
|
|
||||||
QPointF( 6.5, 8.5 ),
|
|
||||||
QPointF( 12, 3 ),
|
|
||||||
QPointF( 15, 6 ),
|
|
||||||
QPointF( 9.5, 11.5 )} );
|
|
||||||
|
|
||||||
painter->setPen( pen );
|
|
||||||
painter->drawLine( QPointF( 5.5, 7.5 ), QPointF( 10.5, 12.5 ) );
|
|
||||||
painter->drawLine( QPointF( 12, 6 ), QPointF( 4.5, 13.5 ) );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DecorationButtonType::Shade:
|
|
||||||
{
|
|
||||||
|
|
||||||
if (isChecked())
|
|
||||||
{
|
|
||||||
|
|
||||||
painter->drawLine( QPointF( 4, 5.5 ), QPointF( 14, 5.5 ) );
|
|
||||||
painter->drawPolyline( QVector<QPointF> {
|
|
||||||
QPointF( 4, 8 ),
|
|
||||||
QPointF( 9, 13 ),
|
|
||||||
QPointF( 14, 8 )} );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
painter->drawLine( QPointF( 4, 5.5 ), QPointF( 14, 5.5 ) );
|
|
||||||
painter->drawPolyline( QVector<QPointF> {
|
|
||||||
QPointF( 4, 13 ),
|
|
||||||
QPointF( 9, 8 ),
|
|
||||||
QPointF( 14, 13 ) });
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
case DecorationButtonType::KeepBelow:
|
|
||||||
{
|
|
||||||
|
|
||||||
painter->drawPolyline( QVector<QPointF> {
|
|
||||||
QPointF( 4, 5 ),
|
|
||||||
QPointF( 9, 10 ),
|
|
||||||
QPointF( 14, 5 ) });
|
|
||||||
|
|
||||||
painter->drawPolyline( QVector<QPointF> {
|
|
||||||
QPointF( 4, 9 ),
|
|
||||||
QPointF( 9, 14 ),
|
|
||||||
QPointF( 14, 9 ) });
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
case DecorationButtonType::KeepAbove:
|
|
||||||
{
|
|
||||||
painter->drawPolyline( QVector<QPointF> {
|
|
||||||
QPointF( 4, 9 ),
|
|
||||||
QPointF( 9, 4 ),
|
|
||||||
QPointF( 14, 9 ) });
|
|
||||||
|
|
||||||
painter->drawPolyline( QVector<QPointF> {
|
|
||||||
QPointF( 4, 13 ),
|
|
||||||
QPointF( 9, 8 ),
|
|
||||||
QPointF( 14, 13 ) });
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
case DecorationButtonType::ApplicationMenu:
|
|
||||||
{
|
|
||||||
painter->drawRect( QRectF( 3.5, 4.5, 11, 1 ) );
|
|
||||||
painter->drawRect( QRectF( 3.5, 8.5, 11, 1 ) );
|
|
||||||
painter->drawRect( QRectF( 3.5, 12.5, 11, 1 ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DecorationButtonType::ContextHelp:
|
|
||||||
{
|
|
||||||
QPainterPath path;
|
|
||||||
path.moveTo( 5, 6 );
|
|
||||||
path.arcTo( QRectF( 5, 3.5, 8, 5 ), 180, -180 );
|
|
||||||
path.cubicTo( QPointF(12.5, 9.5), QPointF( 9, 7.5 ), QPointF( 9, 11.5 ) );
|
|
||||||
painter->drawPath( path );
|
|
||||||
|
|
||||||
painter->drawRect( QRectF( 9, 15, 0.5, 0.5 ) );
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
QColor Button::foregroundColor() const
|
|
||||||
{
|
|
||||||
auto d = qobject_cast<Decoration*>( decoration() );
|
|
||||||
if( !d ) {
|
|
||||||
|
|
||||||
return QColor();
|
|
||||||
|
|
||||||
} else if( isPressed() ) {
|
|
||||||
|
|
||||||
return d->titleBarColor();
|
|
||||||
|
|
||||||
} else if( type() == DecorationButtonType::Close && d->internalSettings()->outlineCloseButton() ) {
|
|
||||||
|
|
||||||
return d->titleBarColor();
|
|
||||||
|
|
||||||
} else if( ( type() == DecorationButtonType::KeepBelow || type() == DecorationButtonType::KeepAbove || type() == DecorationButtonType::Shade ) && isChecked() ) {
|
|
||||||
|
|
||||||
return d->titleBarColor();
|
|
||||||
|
|
||||||
} else if( m_animation->state() == QAbstractAnimation::Running ) {
|
|
||||||
|
|
||||||
return KColorUtils::mix( d->fontColor(), d->titleBarColor(), m_opacity );
|
|
||||||
|
|
||||||
} else if( isHovered() ) {
|
|
||||||
|
|
||||||
return d->titleBarColor();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return d->fontColor();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
QColor Button::backgroundColor() const
|
|
||||||
{
|
|
||||||
auto d = qobject_cast<Decoration*>( decoration() );
|
|
||||||
if( !d ) {
|
|
||||||
|
|
||||||
return QColor();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
auto c = d->client().data();
|
|
||||||
QColor blueColor( c->palette().color( QPalette::Highlight ) );
|
|
||||||
|
|
||||||
if( isPressed() ) {
|
|
||||||
|
|
||||||
if( type() == DecorationButtonType::Close ) return blueColor.darker();
|
|
||||||
else return KColorUtils::mix( d->titleBarColor(), d->fontColor(), 0.3 );
|
|
||||||
|
|
||||||
} else if( ( type() == DecorationButtonType::KeepBelow || type() == DecorationButtonType::KeepAbove || type() == DecorationButtonType::Shade ) && isChecked() ) {
|
|
||||||
|
|
||||||
return d->fontColor();
|
|
||||||
|
|
||||||
} else if( m_animation->state() == QAbstractAnimation::Running ) {
|
|
||||||
|
|
||||||
if( type() == DecorationButtonType::Close )
|
|
||||||
{
|
|
||||||
if( d->internalSettings()->outlineCloseButton() )
|
|
||||||
{
|
|
||||||
|
|
||||||
return c->isActive() ? KColorUtils::mix( blueColor, blueColor.lighter(), m_opacity ) : KColorUtils::mix( blueColor.lighter(), blueColor, m_opacity );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
QColor color( blueColor.lighter() );
|
|
||||||
color.setAlpha( color.alpha()*m_opacity );
|
|
||||||
return color;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
QColor color( d->fontColor() );
|
|
||||||
color.setAlpha( color.alpha()*m_opacity );
|
|
||||||
return color;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if( isHovered() ) {
|
|
||||||
|
|
||||||
if( type() == DecorationButtonType::Close ) return c->isActive() ? blueColor.lighter() : blueColor;
|
|
||||||
else return d->fontColor();
|
|
||||||
|
|
||||||
} else if( type() == DecorationButtonType::Close && d->internalSettings()->outlineCloseButton() ) {
|
|
||||||
|
|
||||||
return c->isActive() ? blueColor : d->fontColor();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return QColor();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Button::reconfigure()
|
|
||||||
{
|
|
||||||
|
|
||||||
// animation
|
|
||||||
auto d = qobject_cast<Decoration*>(decoration());
|
|
||||||
if( d ) m_animation->setDuration( d->animationsDuration() );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
void Button::updateAnimationState( bool hovered )
|
|
||||||
{
|
|
||||||
|
|
||||||
auto d = qobject_cast<Decoration*>(decoration());
|
|
||||||
if( !(d && d->animationsDuration() > 0 ) ) return;
|
|
||||||
|
|
||||||
m_animation->setDirection( hovered ? QAbstractAnimation::Forward : QAbstractAnimation::Backward );
|
|
||||||
if( m_animation->state() != QAbstractAnimation::Running ) m_animation->start();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
@ -1,124 +0,0 @@
|
|||||||
#ifndef BREEZE_BUTTONS_H
|
|
||||||
#define BREEZE_BUTTONS_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
|
|
||||||
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
#include <KDecoration2/DecorationButton>
|
|
||||||
#include "breezedecoration.h"
|
|
||||||
|
|
||||||
#include <QHash>
|
|
||||||
#include <QImage>
|
|
||||||
|
|
||||||
class QVariantAnimation;
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
class Button : public KDecoration2::DecorationButton
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//* constructor
|
|
||||||
explicit Button(QObject *parent, const QVariantList &args);
|
|
||||||
|
|
||||||
//* destructor
|
|
||||||
virtual ~Button() = default;
|
|
||||||
|
|
||||||
//* button creation
|
|
||||||
static Button *create(KDecoration2::DecorationButtonType type, KDecoration2::Decoration *decoration, QObject *parent);
|
|
||||||
|
|
||||||
//* render
|
|
||||||
virtual void paint(QPainter *painter, const QRect &repaintRegion) override;
|
|
||||||
|
|
||||||
//* flag
|
|
||||||
enum Flag
|
|
||||||
{
|
|
||||||
FlagNone,
|
|
||||||
FlagStandalone,
|
|
||||||
FlagFirstInList,
|
|
||||||
FlagLastInList
|
|
||||||
};
|
|
||||||
|
|
||||||
//* flag
|
|
||||||
void setFlag( Flag value )
|
|
||||||
{ m_flag = value; }
|
|
||||||
|
|
||||||
//* standalone buttons
|
|
||||||
bool isStandAlone() const { return m_flag == FlagStandalone; }
|
|
||||||
|
|
||||||
//* offset
|
|
||||||
void setOffset( const QPointF& value )
|
|
||||||
{ m_offset = value; }
|
|
||||||
|
|
||||||
//* horizontal offset, for rendering
|
|
||||||
void setHorizontalOffset( qreal value )
|
|
||||||
{ m_offset.setX( value ); }
|
|
||||||
|
|
||||||
//* vertical offset, for rendering
|
|
||||||
void setVerticalOffset( qreal value )
|
|
||||||
{ m_offset.setY( value ); }
|
|
||||||
|
|
||||||
//* set icon size
|
|
||||||
void setIconSize( const QSize& value )
|
|
||||||
{ m_iconSize = value; }
|
|
||||||
|
|
||||||
//*@name active state change animation
|
|
||||||
//@{
|
|
||||||
void setOpacity( qreal value )
|
|
||||||
{
|
|
||||||
if( m_opacity == value ) return;
|
|
||||||
m_opacity = value;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal opacity() const
|
|
||||||
{ return m_opacity; }
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
|
|
||||||
//* apply configuration changes
|
|
||||||
void reconfigure();
|
|
||||||
|
|
||||||
//* animation state
|
|
||||||
void updateAnimationState(bool);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//* private constructor
|
|
||||||
explicit Button(KDecoration2::DecorationButtonType type, Decoration *decoration, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
//* draw button icon
|
|
||||||
void drawIcon( QPainter *) const;
|
|
||||||
|
|
||||||
//*@name colors
|
|
||||||
//@{
|
|
||||||
QColor foregroundColor() const;
|
|
||||||
QColor backgroundColor() const;
|
|
||||||
//@}
|
|
||||||
|
|
||||||
Flag m_flag = FlagNone;
|
|
||||||
|
|
||||||
//* active state change animation
|
|
||||||
QVariantAnimation *m_animation;
|
|
||||||
|
|
||||||
//* vertical offset (for rendering)
|
|
||||||
QPointF m_offset;
|
|
||||||
|
|
||||||
//* icon size
|
|
||||||
QSize m_iconSize;
|
|
||||||
|
|
||||||
//* active state change opacity
|
|
||||||
qreal m_opacity = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,817 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
|
|
||||||
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
* SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "breezedecoration.h"
|
|
||||||
|
|
||||||
#include "breezesettingsprovider.h"
|
|
||||||
#include "config-breeze.h"
|
|
||||||
#include "config/breezeconfigwidget.h"
|
|
||||||
|
|
||||||
#include "breezebutton.h"
|
|
||||||
#include "breezesizegrip.h"
|
|
||||||
|
|
||||||
#include "breezeboxshadowrenderer.h"
|
|
||||||
|
|
||||||
#include <KDecoration2/DecorationButtonGroup>
|
|
||||||
#include <KDecoration2/DecorationShadow>
|
|
||||||
|
|
||||||
#include <KConfigGroup>
|
|
||||||
#include <KColorUtils>
|
|
||||||
#include <KSharedConfig>
|
|
||||||
#include <KPluginFactory>
|
|
||||||
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QTextStream>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QDBusConnection>
|
|
||||||
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
#include <QX11Info>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
K_PLUGIN_FACTORY_WITH_JSON(
|
|
||||||
BreezeDecoFactory,
|
|
||||||
"breeze.json",
|
|
||||||
registerPlugin<Breeze::Decoration>();
|
|
||||||
registerPlugin<Breeze::Button>(QStringLiteral("button"));
|
|
||||||
registerPlugin<Breeze::ConfigWidget>(QStringLiteral("kcmodule"));
|
|
||||||
)
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
struct ShadowParams {
|
|
||||||
ShadowParams()
|
|
||||||
: offset(QPoint(0, 0))
|
|
||||||
, radius(0)
|
|
||||||
, opacity(0) {}
|
|
||||||
|
|
||||||
ShadowParams(const QPoint &offset, int radius, qreal opacity)
|
|
||||||
: offset(offset)
|
|
||||||
, radius(radius)
|
|
||||||
, opacity(opacity) {}
|
|
||||||
|
|
||||||
QPoint offset;
|
|
||||||
int radius;
|
|
||||||
qreal opacity;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CompositeShadowParams {
|
|
||||||
CompositeShadowParams() = default;
|
|
||||||
|
|
||||||
CompositeShadowParams(
|
|
||||||
const QPoint &offset,
|
|
||||||
const ShadowParams &shadow1,
|
|
||||||
const ShadowParams &shadow2)
|
|
||||||
: offset(offset)
|
|
||||||
, shadow1(shadow1)
|
|
||||||
, shadow2(shadow2) {}
|
|
||||||
|
|
||||||
bool isNone() const {
|
|
||||||
return qMax(shadow1.radius, shadow2.radius) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPoint offset;
|
|
||||||
ShadowParams shadow1;
|
|
||||||
ShadowParams shadow2;
|
|
||||||
};
|
|
||||||
|
|
||||||
const CompositeShadowParams s_shadowParams[] = {
|
|
||||||
// None
|
|
||||||
CompositeShadowParams(),
|
|
||||||
// Small
|
|
||||||
CompositeShadowParams(
|
|
||||||
QPoint(0, 4),
|
|
||||||
ShadowParams(QPoint(0, 0), 16, 1),
|
|
||||||
ShadowParams(QPoint(0, -2), 8, 0.4)),
|
|
||||||
// Medium
|
|
||||||
CompositeShadowParams(
|
|
||||||
QPoint(0, 8),
|
|
||||||
ShadowParams(QPoint(0, 0), 32, 0.9),
|
|
||||||
ShadowParams(QPoint(0, -4), 16, 0.3)),
|
|
||||||
// Large
|
|
||||||
CompositeShadowParams(
|
|
||||||
QPoint(0, 12),
|
|
||||||
ShadowParams(QPoint(0, 0), 48, 0.8),
|
|
||||||
ShadowParams(QPoint(0, -6), 24, 0.2)),
|
|
||||||
// Very large
|
|
||||||
CompositeShadowParams(
|
|
||||||
QPoint(0, 16),
|
|
||||||
ShadowParams(QPoint(0, 0), 64, 0.7),
|
|
||||||
ShadowParams(QPoint(0, -8), 32, 0.1)),
|
|
||||||
};
|
|
||||||
|
|
||||||
inline CompositeShadowParams lookupShadowParams(int size)
|
|
||||||
{
|
|
||||||
switch (size) {
|
|
||||||
case Breeze::InternalSettings::ShadowNone:
|
|
||||||
return s_shadowParams[0];
|
|
||||||
case Breeze::InternalSettings::ShadowSmall:
|
|
||||||
return s_shadowParams[1];
|
|
||||||
case Breeze::InternalSettings::ShadowMedium:
|
|
||||||
return s_shadowParams[2];
|
|
||||||
case Breeze::InternalSettings::ShadowLarge:
|
|
||||||
return s_shadowParams[3];
|
|
||||||
case Breeze::InternalSettings::ShadowVeryLarge:
|
|
||||||
return s_shadowParams[4];
|
|
||||||
default:
|
|
||||||
// Fallback to the Large size.
|
|
||||||
return s_shadowParams[3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
using KDecoration2::ColorRole;
|
|
||||||
using KDecoration2::ColorGroup;
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
static int g_sDecoCount = 0;
|
|
||||||
static int g_shadowSizeEnum = InternalSettings::ShadowLarge;
|
|
||||||
static int g_shadowStrength = 255;
|
|
||||||
static QColor g_shadowColor = Qt::black;
|
|
||||||
static QSharedPointer<KDecoration2::DecorationShadow> g_sShadow;
|
|
||||||
static QSharedPointer<KDecoration2::DecorationShadow> g_sShadowInactive;
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
Decoration::Decoration(QObject *parent, const QVariantList &args)
|
|
||||||
: KDecoration2::Decoration(parent, args)
|
|
||||||
, m_animation( new QVariantAnimation( this ) )
|
|
||||||
, m_shadowAnimation( new QVariantAnimation( this ) )
|
|
||||||
{
|
|
||||||
g_sDecoCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
Decoration::~Decoration()
|
|
||||||
{
|
|
||||||
g_sDecoCount--;
|
|
||||||
if (g_sDecoCount == 0) {
|
|
||||||
// last deco destroyed, clean up shadow
|
|
||||||
g_sShadow.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteSizeGrip();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::setOpacity( qreal value )
|
|
||||||
{
|
|
||||||
if( m_opacity == value ) return;
|
|
||||||
m_opacity = value;
|
|
||||||
update();
|
|
||||||
|
|
||||||
if( m_sizeGrip ) m_sizeGrip->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
QColor Decoration::titleBarColor() const
|
|
||||||
{
|
|
||||||
|
|
||||||
auto c = client().data();
|
|
||||||
if( hideTitleBar() ) return c->color( ColorGroup::Inactive, ColorRole::TitleBar );
|
|
||||||
else if( m_animation->state() == QAbstractAnimation::Running )
|
|
||||||
{
|
|
||||||
return KColorUtils::mix(
|
|
||||||
c->color( ColorGroup::Inactive, ColorRole::TitleBar ),
|
|
||||||
c->color( ColorGroup::Active, ColorRole::TitleBar ),
|
|
||||||
m_opacity );
|
|
||||||
} else return c->color( c->isActive() ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::TitleBar );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
QColor Decoration::outlineColor() const
|
|
||||||
{
|
|
||||||
|
|
||||||
auto c( client().data() );
|
|
||||||
if( !m_internalSettings->drawTitleBarSeparator() ) return QColor();
|
|
||||||
if( m_animation->state() == QAbstractAnimation::Running )
|
|
||||||
{
|
|
||||||
QColor color( c->palette().color( QPalette::Highlight ) );
|
|
||||||
color.setAlpha( color.alpha()*m_opacity );
|
|
||||||
return color;
|
|
||||||
} else if( c->isActive() ) return c->palette().color( QPalette::Highlight );
|
|
||||||
else return QColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
QColor Decoration::fontColor() const
|
|
||||||
{
|
|
||||||
|
|
||||||
auto c = client().data();
|
|
||||||
if( m_animation->state() == QAbstractAnimation::Running )
|
|
||||||
{
|
|
||||||
return KColorUtils::mix(
|
|
||||||
c->color( ColorGroup::Inactive, ColorRole::Foreground ),
|
|
||||||
c->color( ColorGroup::Active, ColorRole::Foreground ),
|
|
||||||
m_opacity );
|
|
||||||
} else return c->color( c->isActive() ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::Foreground );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::init()
|
|
||||||
{
|
|
||||||
auto c = client().data();
|
|
||||||
|
|
||||||
// active state change animation
|
|
||||||
// It is important start and end value are of the same type, hence 0.0 and not just 0
|
|
||||||
m_animation->setStartValue( 0.0 );
|
|
||||||
m_animation->setEndValue( 1.0 );
|
|
||||||
// Linear to have the same easing as Breeze animations
|
|
||||||
m_animation->setEasingCurve( QEasingCurve::Linear );
|
|
||||||
connect(m_animation, &QVariantAnimation::valueChanged, this, [this](const QVariant &value) {
|
|
||||||
setOpacity(value.toReal());
|
|
||||||
});
|
|
||||||
|
|
||||||
m_shadowAnimation->setStartValue( 0.0 );
|
|
||||||
m_shadowAnimation->setEndValue( 1.0 );
|
|
||||||
m_shadowAnimation->setEasingCurve( QEasingCurve::InCubic );
|
|
||||||
connect(m_shadowAnimation, &QVariantAnimation::valueChanged, this, [this](const QVariant& value) {
|
|
||||||
m_shadowOpacity = value.toReal();
|
|
||||||
updateShadow();
|
|
||||||
});
|
|
||||||
|
|
||||||
// use DBus connection to update on breeze configuration change
|
|
||||||
auto dbus = QDBusConnection::sessionBus();
|
|
||||||
dbus.connect( QString(),
|
|
||||||
QStringLiteral( "/KGlobalSettings" ),
|
|
||||||
QStringLiteral( "org.kde.KGlobalSettings" ),
|
|
||||||
QStringLiteral( "notifyChange" ), this, SLOT(reconfigure()) );
|
|
||||||
|
|
||||||
reconfigure();
|
|
||||||
updateTitleBar();
|
|
||||||
auto s = settings();
|
|
||||||
connect(s.data(), &KDecoration2::DecorationSettings::borderSizeChanged, this, &Decoration::recalculateBorders);
|
|
||||||
|
|
||||||
// a change in font might cause the borders to change
|
|
||||||
connect(s.data(), &KDecoration2::DecorationSettings::fontChanged, this, &Decoration::recalculateBorders);
|
|
||||||
connect(s.data(), &KDecoration2::DecorationSettings::spacingChanged, this, &Decoration::recalculateBorders);
|
|
||||||
|
|
||||||
// buttons
|
|
||||||
connect(s.data(), &KDecoration2::DecorationSettings::spacingChanged, this, &Decoration::updateButtonsGeometryDelayed);
|
|
||||||
connect(s.data(), &KDecoration2::DecorationSettings::decorationButtonsLeftChanged, this, &Decoration::updateButtonsGeometryDelayed);
|
|
||||||
connect(s.data(), &KDecoration2::DecorationSettings::decorationButtonsRightChanged, this, &Decoration::updateButtonsGeometryDelayed);
|
|
||||||
|
|
||||||
// full reconfiguration
|
|
||||||
connect(s.data(), &KDecoration2::DecorationSettings::reconfigured, this, &Decoration::reconfigure);
|
|
||||||
connect(s.data(), &KDecoration2::DecorationSettings::reconfigured, SettingsProvider::self(), &SettingsProvider::reconfigure, Qt::UniqueConnection );
|
|
||||||
connect(s.data(), &KDecoration2::DecorationSettings::reconfigured, this, &Decoration::updateButtonsGeometryDelayed);
|
|
||||||
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::adjacentScreenEdgesChanged, this, &Decoration::recalculateBorders);
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::maximizedHorizontallyChanged, this, &Decoration::recalculateBorders);
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::maximizedVerticallyChanged, this, &Decoration::recalculateBorders);
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::shadedChanged, this, &Decoration::recalculateBorders);
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::captionChanged, this,
|
|
||||||
[this]()
|
|
||||||
{
|
|
||||||
// update the caption area
|
|
||||||
update(titleBar());
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::activeChanged, this, &Decoration::updateAnimationState);
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::widthChanged, this, &Decoration::updateTitleBar);
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateTitleBar);
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::setOpaque);
|
|
||||||
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::widthChanged, this, &Decoration::updateButtonsGeometry);
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateButtonsGeometry);
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::adjacentScreenEdgesChanged, this, &Decoration::updateButtonsGeometry);
|
|
||||||
connect(c, &KDecoration2::DecoratedClient::shadedChanged, this, &Decoration::updateButtonsGeometry);
|
|
||||||
|
|
||||||
createButtons();
|
|
||||||
updateShadow();
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::updateTitleBar()
|
|
||||||
{
|
|
||||||
auto s = settings();
|
|
||||||
auto c = client().data();
|
|
||||||
const bool maximized = isMaximized();
|
|
||||||
const int width = maximized ? c->width() : c->width() - 2*s->largeSpacing()*Metrics::TitleBar_SideMargin;
|
|
||||||
const int height = maximized ? borderTop() : borderTop() - s->smallSpacing()*Metrics::TitleBar_TopMargin;
|
|
||||||
const int x = maximized ? 0 : s->largeSpacing()*Metrics::TitleBar_SideMargin;
|
|
||||||
const int y = maximized ? 0 : s->smallSpacing()*Metrics::TitleBar_TopMargin;
|
|
||||||
setTitleBar(QRect(x, y, width, height));
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::updateAnimationState()
|
|
||||||
{
|
|
||||||
if( m_shadowAnimation->duration() > 0 )
|
|
||||||
{
|
|
||||||
|
|
||||||
auto c = client().data();
|
|
||||||
m_shadowAnimation->setDirection( c->isActive() ? QAbstractAnimation::Forward : QAbstractAnimation::Backward );
|
|
||||||
if( m_shadowAnimation->state() != QAbstractAnimation::Running ) m_shadowAnimation->start();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
updateShadow();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_animation->duration() > 0 )
|
|
||||||
{
|
|
||||||
|
|
||||||
auto c = client().data();
|
|
||||||
m_animation->setDirection( c->isActive() ? QAbstractAnimation::Forward : QAbstractAnimation::Backward );
|
|
||||||
if( m_animation->state() != QAbstractAnimation::Running ) m_animation->start();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
update();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::updateSizeGripVisibility()
|
|
||||||
{
|
|
||||||
auto c = client().data();
|
|
||||||
if( m_sizeGrip )
|
|
||||||
{ m_sizeGrip->setVisible( c->isResizeable() && !isMaximized() && !c->isShaded() ); }
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
int Decoration::borderSize(bool bottom) const
|
|
||||||
{
|
|
||||||
const int baseSize = settings()->smallSpacing();
|
|
||||||
return baseSize*Metrics::Frame_BorderSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::reconfigure()
|
|
||||||
{
|
|
||||||
|
|
||||||
m_internalSettings = SettingsProvider::self()->internalSettings( this );
|
|
||||||
|
|
||||||
// animation
|
|
||||||
|
|
||||||
KSharedConfig::Ptr config = KSharedConfig::openConfig();
|
|
||||||
const KConfigGroup cg(config, QStringLiteral("KDE"));
|
|
||||||
|
|
||||||
m_animation->setDuration(0);
|
|
||||||
// Syncing anis between client and decoration is troublesome, so we're not using
|
|
||||||
// any animations right now.
|
|
||||||
// m_animation->setDuration( cg.readEntry("AnimationDurationFactor", 1.0f) * 100.0f );
|
|
||||||
|
|
||||||
// But the shadow is fine to animate like this!
|
|
||||||
m_shadowAnimation->setDuration( cg.readEntry("AnimationDurationFactor", 1.0f) * 100.0f );
|
|
||||||
|
|
||||||
// borders
|
|
||||||
recalculateBorders();
|
|
||||||
|
|
||||||
// shadow
|
|
||||||
updateShadow();
|
|
||||||
|
|
||||||
// size grip
|
|
||||||
deleteSizeGrip();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::recalculateBorders()
|
|
||||||
{
|
|
||||||
auto c = client().data();
|
|
||||||
auto s = settings();
|
|
||||||
|
|
||||||
// left, right and bottom borders
|
|
||||||
const int left = borderSize();
|
|
||||||
const int right = borderSize();
|
|
||||||
const int bottom = c->isShaded() ? 0 : borderSize();
|
|
||||||
|
|
||||||
int top = 0;
|
|
||||||
if( hideTitleBar() ) top = bottom;
|
|
||||||
else {
|
|
||||||
|
|
||||||
QFontMetrics fm(s->font());
|
|
||||||
top += qMax(fm.height(), buttonHeight() );
|
|
||||||
|
|
||||||
// padding below
|
|
||||||
// extra pixel is used for the active window outline
|
|
||||||
const int baseSize = s->smallSpacing();
|
|
||||||
top += baseSize*Metrics::TitleBar_BottomMargin + 1;
|
|
||||||
|
|
||||||
// padding above
|
|
||||||
top += baseSize*TitleBar_TopMargin;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
setBorders(QMargins(left, top, right, bottom));
|
|
||||||
|
|
||||||
// extended sizes
|
|
||||||
const int extSize = s->largeSpacing();
|
|
||||||
int extSides = 0;
|
|
||||||
int extBottom = 0;
|
|
||||||
|
|
||||||
setResizeOnlyBorders(QMargins(extSides, 0, extSides, extBottom));
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::createButtons()
|
|
||||||
{
|
|
||||||
m_leftButtons = new KDecoration2::DecorationButtonGroup(KDecoration2::DecorationButtonGroup::Position::Left, this, &Button::create);
|
|
||||||
m_rightButtons = new KDecoration2::DecorationButtonGroup(KDecoration2::DecorationButtonGroup::Position::Right, this, &Button::create);
|
|
||||||
updateButtonsGeometry();
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::updateButtonsGeometryDelayed()
|
|
||||||
{ QTimer::singleShot( 0, this, &Decoration::updateButtonsGeometry ); }
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::updateButtonsGeometry()
|
|
||||||
{
|
|
||||||
const auto s = settings();
|
|
||||||
|
|
||||||
// adjust button position
|
|
||||||
const int bHeight = captionHeight() + (isTopEdge() ? s->smallSpacing()*Metrics::TitleBar_TopMargin:0);
|
|
||||||
const int bWidth = buttonHeight();
|
|
||||||
const int verticalOffset = (isTopEdge() ? s->smallSpacing()*Metrics::TitleBar_TopMargin:0) + (captionHeight()-buttonHeight())/2;
|
|
||||||
foreach( const QPointer<KDecoration2::DecorationButton>& button, m_leftButtons->buttons() + m_rightButtons->buttons() )
|
|
||||||
{
|
|
||||||
button.data()->setGeometry( QRectF( QPoint( 0, 0 ), QSizeF( bWidth, bHeight ) ) );
|
|
||||||
static_cast<Button*>( button.data() )->setOffset( QPointF( 0, verticalOffset ) );
|
|
||||||
static_cast<Button*>( button.data() )->setIconSize( QSize( bWidth, bWidth ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// padding
|
|
||||||
const int vPadding = isTopEdge() ? 0 : s->smallSpacing()*Metrics::TitleBar_TopMargin;
|
|
||||||
const int hPadding = s->smallSpacing()*Metrics::TitleBar_SideMargin;
|
|
||||||
|
|
||||||
// left buttons
|
|
||||||
if( !m_leftButtons->buttons().isEmpty() )
|
|
||||||
{
|
|
||||||
// spacing
|
|
||||||
m_leftButtons->setSpacing(s->smallSpacing()*Metrics::TitleBar_ButtonSpacing);
|
|
||||||
m_leftButtons->setPos(QPointF(hPadding + borderLeft(), vPadding));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// right buttons
|
|
||||||
if( !m_rightButtons->buttons().isEmpty() )
|
|
||||||
{
|
|
||||||
// spacing
|
|
||||||
m_rightButtons->setSpacing(s->smallSpacing()*Metrics::TitleBar_ButtonSpacing);
|
|
||||||
m_rightButtons->setPos(QPointF(size().width() - m_rightButtons->geometry().width() - hPadding - borderRight(), vPadding));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
update();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::paint(QPainter *painter, const QRect &repaintRegion)
|
|
||||||
{
|
|
||||||
// TODO: optimize based on repaintRegion
|
|
||||||
auto c = client().data();
|
|
||||||
auto s = settings();
|
|
||||||
const int radius = s->smallSpacing()*Metrics::Frame_FrameRadius;
|
|
||||||
|
|
||||||
// paint background
|
|
||||||
if( !c->isShaded() )
|
|
||||||
{
|
|
||||||
painter->fillRect(rect(), Qt::transparent);
|
|
||||||
painter->save();
|
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
|
||||||
painter->setPen(Qt::NoPen);
|
|
||||||
painter->setBrush( c->color( c->isActive() ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::Frame ) );
|
|
||||||
|
|
||||||
// clip away the top part
|
|
||||||
if( !hideTitleBar() ) painter->setClipRect(0, borderTop(), size().width(), size().height() - borderTop(), Qt::IntersectClip);
|
|
||||||
|
|
||||||
if( s->isAlphaChannelSupported() ) painter->drawRoundedRect(rect(),
|
|
||||||
isBottomEdge() ? 0:radius,
|
|
||||||
isBottomEdge() ? 0:radius);
|
|
||||||
else painter->drawRect( rect() );
|
|
||||||
|
|
||||||
painter->restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !hideTitleBar() ) paintTitleBar(painter, repaintRegion);
|
|
||||||
|
|
||||||
if( !s->isAlphaChannelSupported() )
|
|
||||||
{
|
|
||||||
painter->save();
|
|
||||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
|
||||||
painter->setBrush( Qt::NoBrush );
|
|
||||||
painter->setPen( c->isActive() ?
|
|
||||||
c->color( ColorGroup::Active, ColorRole::TitleBar ):
|
|
||||||
c->color( ColorGroup::Inactive, ColorRole::Foreground ) );
|
|
||||||
|
|
||||||
painter->drawRect( rect().adjusted( 0, 0, -1, -1 ) );
|
|
||||||
painter->restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::paintTitleBar(QPainter *painter, const QRect &repaintRegion)
|
|
||||||
{
|
|
||||||
const auto c = client().data();
|
|
||||||
const QRect titleRect(QPoint(0, 0), QSize(size().width(), borderTop()));
|
|
||||||
|
|
||||||
if ( !titleRect.intersects(repaintRegion) ) return;
|
|
||||||
|
|
||||||
painter->save();
|
|
||||||
painter->setPen(Qt::NoPen);
|
|
||||||
|
|
||||||
// render a linear gradient on title area
|
|
||||||
if( c->isActive() && m_internalSettings->drawBackgroundGradient() )
|
|
||||||
{
|
|
||||||
|
|
||||||
const QColor titleBarColor( this->titleBarColor() );
|
|
||||||
QLinearGradient gradient( 0, 0, 0, titleRect.height() );
|
|
||||||
gradient.setColorAt(0.0, titleBarColor.lighter( 120 ) );
|
|
||||||
gradient.setColorAt(0.8, titleBarColor);
|
|
||||||
painter->setBrush(gradient);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
painter->setBrush( titleBarColor() );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
auto s = settings();
|
|
||||||
const int radius = s->smallSpacing()*Metrics::Frame_FrameRadius;
|
|
||||||
if( isMaximized() || !s->isAlphaChannelSupported() )
|
|
||||||
{
|
|
||||||
|
|
||||||
painter->drawRect(titleRect);
|
|
||||||
|
|
||||||
} else if( c->isShaded() ) {
|
|
||||||
|
|
||||||
painter->drawRoundedRect(titleRect, radius, radius);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
painter->setClipRect(titleRect, Qt::IntersectClip);
|
|
||||||
|
|
||||||
// the rect is made a little bit larger to be able to clip away the rounded corners at the bottom and sides
|
|
||||||
painter->drawRoundedRect(titleRect.adjusted(
|
|
||||||
isLeftEdge() ? -radius:0,
|
|
||||||
isTopEdge() ? -radius:0,
|
|
||||||
isRightEdge() ? radius:0,
|
|
||||||
radius),
|
|
||||||
radius, radius);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const QColor outlineColor( this->outlineColor() );
|
|
||||||
if( !c->isShaded() && outlineColor.isValid() )
|
|
||||||
{
|
|
||||||
// outline
|
|
||||||
painter->setRenderHint( QPainter::Antialiasing, false );
|
|
||||||
painter->setBrush( Qt::NoBrush );
|
|
||||||
painter->setPen( outlineColor );
|
|
||||||
painter->drawLine( titleRect.bottomLeft(), titleRect.bottomRight() );
|
|
||||||
}
|
|
||||||
|
|
||||||
painter->restore();
|
|
||||||
|
|
||||||
// draw caption
|
|
||||||
painter->setFont(s->font());
|
|
||||||
painter->setPen( fontColor() );
|
|
||||||
const auto cR = captionRect();
|
|
||||||
const QString caption = painter->fontMetrics().elidedText(c->caption(), Qt::ElideMiddle, cR.first.width());
|
|
||||||
painter->drawText(cR.first, cR.second | Qt::TextSingleLine, caption);
|
|
||||||
|
|
||||||
// draw all buttons
|
|
||||||
m_leftButtons->paint(painter, repaintRegion);
|
|
||||||
m_rightButtons->paint(painter, repaintRegion);
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
int Decoration::buttonHeight() const
|
|
||||||
{
|
|
||||||
const int baseSize = settings()->gridUnit();
|
|
||||||
switch( m_internalSettings->buttonSize() )
|
|
||||||
{
|
|
||||||
case InternalSettings::ButtonTiny: return baseSize;
|
|
||||||
case InternalSettings::ButtonSmall: return baseSize*1.5;
|
|
||||||
default:
|
|
||||||
case InternalSettings::ButtonDefault: return baseSize*2;
|
|
||||||
case InternalSettings::ButtonLarge: return baseSize*2.5;
|
|
||||||
case InternalSettings::ButtonVeryLarge: return baseSize*3.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
int Decoration::captionHeight() const
|
|
||||||
{ return hideTitleBar() ? borderTop() : borderTop() - settings()->smallSpacing()*(Metrics::TitleBar_BottomMargin + Metrics::TitleBar_TopMargin ) - 1; }
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
QPair<QRect,Qt::Alignment> Decoration::captionRect() const
|
|
||||||
{
|
|
||||||
if( hideTitleBar() ) return qMakePair( QRect(), Qt::AlignCenter );
|
|
||||||
else {
|
|
||||||
|
|
||||||
auto c = client().data();
|
|
||||||
const int leftOffset = m_leftButtons->buttons().isEmpty() ?
|
|
||||||
Metrics::TitleBar_SideMargin*settings()->smallSpacing():
|
|
||||||
m_leftButtons->geometry().x() + m_leftButtons->geometry().width() + Metrics::TitleBar_SideMargin*settings()->smallSpacing();
|
|
||||||
|
|
||||||
const int rightOffset = m_rightButtons->buttons().isEmpty() ?
|
|
||||||
Metrics::TitleBar_SideMargin*settings()->smallSpacing() :
|
|
||||||
size().width() - m_rightButtons->geometry().x() + Metrics::TitleBar_SideMargin*settings()->smallSpacing();
|
|
||||||
|
|
||||||
const int yOffset = settings()->smallSpacing()*Metrics::TitleBar_TopMargin;
|
|
||||||
const QRect maxRect( leftOffset, yOffset, size().width() - leftOffset - rightOffset, captionHeight() );
|
|
||||||
|
|
||||||
switch( m_internalSettings->titleAlignment() )
|
|
||||||
{
|
|
||||||
case InternalSettings::AlignLeft:
|
|
||||||
return qMakePair( maxRect, Qt::AlignVCenter|Qt::AlignLeft );
|
|
||||||
|
|
||||||
case InternalSettings::AlignRight:
|
|
||||||
return qMakePair( maxRect, Qt::AlignVCenter|Qt::AlignRight );
|
|
||||||
|
|
||||||
case InternalSettings::AlignCenter:
|
|
||||||
return qMakePair( maxRect, Qt::AlignCenter );
|
|
||||||
|
|
||||||
default:
|
|
||||||
case InternalSettings::AlignCenterFullWidth:
|
|
||||||
{
|
|
||||||
|
|
||||||
// full caption rect
|
|
||||||
const QRect fullRect = QRect( 0, yOffset, size().width(), captionHeight() );
|
|
||||||
QRect boundingRect( settings()->fontMetrics().boundingRect( c->caption()).toRect() );
|
|
||||||
|
|
||||||
// text bounding rect
|
|
||||||
boundingRect.setTop( yOffset );
|
|
||||||
boundingRect.setHeight( captionHeight() );
|
|
||||||
boundingRect.moveLeft( ( size().width() - boundingRect.width() )/2 );
|
|
||||||
|
|
||||||
if( boundingRect.left() < leftOffset ) return qMakePair( maxRect, Qt::AlignVCenter|Qt::AlignLeft );
|
|
||||||
else if( boundingRect.right() > size().width() - rightOffset ) return qMakePair( maxRect, Qt::AlignVCenter|Qt::AlignRight );
|
|
||||||
else return qMakePair(fullRect, Qt::AlignCenter);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
void Decoration::updateShadow()
|
|
||||||
{
|
|
||||||
const auto s = Decoration::settings();
|
|
||||||
|
|
||||||
// Animated case, no cached shadow object
|
|
||||||
if ( (m_shadowAnimation->state() == QAbstractAnimation::Running) && (m_shadowOpacity != 0.0) && (m_shadowOpacity != 1.0) )
|
|
||||||
{
|
|
||||||
setShadow(createShadowObject(m_internalSettings, 0.5 + m_shadowOpacity * 0.5, s->smallSpacing()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_shadowSizeEnum != m_internalSettings->shadowSize()
|
|
||||||
|| g_shadowStrength != m_internalSettings->shadowStrength()
|
|
||||||
|| g_shadowColor != m_internalSettings->shadowColor())
|
|
||||||
{
|
|
||||||
g_sShadow.clear();
|
|
||||||
g_sShadowInactive.clear();
|
|
||||||
g_shadowSizeEnum = m_internalSettings->shadowSize();
|
|
||||||
g_shadowStrength = m_internalSettings->shadowStrength();
|
|
||||||
g_shadowColor = m_internalSettings->shadowColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto c = client().toStrongRef();
|
|
||||||
auto& shadow = (c->isActive()) ? g_sShadow : g_sShadowInactive;
|
|
||||||
if ( !shadow )
|
|
||||||
{
|
|
||||||
shadow = createShadowObject(m_internalSettings, c->isActive() ? 1.0 : 0.5, s->smallSpacing());
|
|
||||||
}
|
|
||||||
setShadow(shadow);
|
|
||||||
}
|
|
||||||
|
|
||||||
//________________________________________________________________
|
|
||||||
QSharedPointer<KDecoration2::DecorationShadow> Decoration::createShadowObject(const InternalSettingsPtr& internalSettings, const float strengthScale, const int scale)
|
|
||||||
{
|
|
||||||
const CompositeShadowParams params = lookupShadowParams(internalSettings->shadowSize());
|
|
||||||
if (params.isNone())
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto withOpacity = [](const QColor& color, qreal opacity) -> QColor {
|
|
||||||
QColor c(color);
|
|
||||||
c.setAlphaF(opacity);
|
|
||||||
return c;
|
|
||||||
};
|
|
||||||
|
|
||||||
const int radius = scale*Metrics::Frame_FrameRadius;
|
|
||||||
|
|
||||||
const QSize boxSize = BoxShadowRenderer::calculateMinimumBoxSize(params.shadow1.radius)
|
|
||||||
.expandedTo(BoxShadowRenderer::calculateMinimumBoxSize(params.shadow2.radius));
|
|
||||||
|
|
||||||
BoxShadowRenderer shadowRenderer;
|
|
||||||
shadowRenderer.setBorderRadius(radius + 0.5);
|
|
||||||
shadowRenderer.setBoxSize(boxSize);
|
|
||||||
shadowRenderer.setDevicePixelRatio(1.0); // TODO: Create HiDPI shadows?
|
|
||||||
|
|
||||||
const qreal strength = internalSettings->shadowStrength() / 255.0 * strengthScale;
|
|
||||||
shadowRenderer.addShadow(params.shadow1.offset, params.shadow1.radius,
|
|
||||||
withOpacity(internalSettings->shadowColor(), params.shadow1.opacity * strength));
|
|
||||||
shadowRenderer.addShadow(params.shadow2.offset, params.shadow2.radius,
|
|
||||||
withOpacity(internalSettings->shadowColor(), params.shadow2.opacity * strength));
|
|
||||||
|
|
||||||
QImage shadowTexture = shadowRenderer.render();
|
|
||||||
|
|
||||||
QPainter painter(&shadowTexture);
|
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
|
||||||
|
|
||||||
const QRect outerRect = shadowTexture.rect();
|
|
||||||
|
|
||||||
QRect boxRect(QPoint(0, 0), boxSize);
|
|
||||||
boxRect.moveCenter(outerRect.center());
|
|
||||||
|
|
||||||
// Mask out inner rect.
|
|
||||||
const QMargins padding = QMargins(
|
|
||||||
boxRect.left() - outerRect.left() - Metrics::Shadow_Overlap - params.offset.x(),
|
|
||||||
boxRect.top() - outerRect.top() - Metrics::Shadow_Overlap - params.offset.y(),
|
|
||||||
outerRect.right() - boxRect.right() - Metrics::Shadow_Overlap + params.offset.x(),
|
|
||||||
outerRect.bottom() - boxRect.bottom() - Metrics::Shadow_Overlap + params.offset.y());
|
|
||||||
const QRect innerRect = outerRect - padding;
|
|
||||||
|
|
||||||
painter.setPen(Qt::NoPen);
|
|
||||||
painter.setBrush(Qt::black);
|
|
||||||
painter.setCompositionMode(QPainter::CompositionMode_DestinationOut);
|
|
||||||
painter.drawRoundedRect(
|
|
||||||
innerRect,
|
|
||||||
radius + 0.5,
|
|
||||||
radius + 0.5);
|
|
||||||
|
|
||||||
// Draw outline.
|
|
||||||
painter.setPen(withOpacity(internalSettings->shadowColor(), 0.2 * strength));
|
|
||||||
painter.setBrush(Qt::NoBrush);
|
|
||||||
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
|
||||||
painter.drawRoundedRect(
|
|
||||||
innerRect,
|
|
||||||
radius - 0.5,
|
|
||||||
radius - 0.5);
|
|
||||||
|
|
||||||
painter.end();
|
|
||||||
|
|
||||||
auto ret = QSharedPointer<KDecoration2::DecorationShadow>::create();
|
|
||||||
ret->setPadding(padding);
|
|
||||||
ret->setInnerShadowRect(QRect(outerRect.center(), QSize(1, 1)));
|
|
||||||
ret->setShadow(shadowTexture);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
//_________________________________________________________________
|
|
||||||
void Decoration::createSizeGrip()
|
|
||||||
{
|
|
||||||
|
|
||||||
// do nothing if size grip already exist
|
|
||||||
if( m_sizeGrip ) return;
|
|
||||||
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
if( !QX11Info::isPlatformX11() ) return;
|
|
||||||
|
|
||||||
// access client
|
|
||||||
auto c = client().data();
|
|
||||||
if( !c ) return;
|
|
||||||
|
|
||||||
if( c->windowId() != 0 )
|
|
||||||
{
|
|
||||||
m_sizeGrip = new SizeGrip( this );
|
|
||||||
connect( c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateSizeGripVisibility );
|
|
||||||
connect( c, &KDecoration2::DecoratedClient::shadedChanged, this, &Decoration::updateSizeGripVisibility );
|
|
||||||
connect( c, &KDecoration2::DecoratedClient::resizeableChanged, this, &Decoration::updateSizeGripVisibility );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_________________________________________________________________
|
|
||||||
void Decoration::deleteSizeGrip()
|
|
||||||
{
|
|
||||||
if( m_sizeGrip )
|
|
||||||
{
|
|
||||||
m_sizeGrip->deleteLater();
|
|
||||||
m_sizeGrip = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
|
|
||||||
#include "breezedecoration.moc"
|
|
||||||
@ -1,170 +0,0 @@
|
|||||||
#ifndef BREEZE_DECORATION_H
|
|
||||||
#define BREEZE_DECORATION_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
|
|
||||||
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "breeze.h"
|
|
||||||
#include "breezesettings.h"
|
|
||||||
|
|
||||||
#include <KDecoration2/Decoration>
|
|
||||||
#include <KDecoration2/DecoratedClient>
|
|
||||||
#include <KDecoration2/DecorationSettings>
|
|
||||||
|
|
||||||
#include <QPalette>
|
|
||||||
#include <QVariant>
|
|
||||||
#include <QVariantAnimation>
|
|
||||||
|
|
||||||
class QVariantAnimation;
|
|
||||||
|
|
||||||
namespace KDecoration2
|
|
||||||
{
|
|
||||||
class DecorationButton;
|
|
||||||
class DecorationButtonGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
class SizeGrip;
|
|
||||||
class Decoration : public KDecoration2::Decoration
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//* constructor
|
|
||||||
explicit Decoration(QObject *parent = nullptr, const QVariantList &args = QVariantList());
|
|
||||||
|
|
||||||
//* destructor
|
|
||||||
virtual ~Decoration();
|
|
||||||
|
|
||||||
//* paint
|
|
||||||
void paint(QPainter *painter, const QRect &repaintRegion) override;
|
|
||||||
|
|
||||||
//* internal settings
|
|
||||||
InternalSettingsPtr internalSettings() const
|
|
||||||
{ return m_internalSettings; }
|
|
||||||
|
|
||||||
qreal animationsDuration() const
|
|
||||||
{ return m_animation->duration();}
|
|
||||||
|
|
||||||
//* caption height
|
|
||||||
int captionHeight() const;
|
|
||||||
|
|
||||||
//* button height
|
|
||||||
int buttonHeight() const;
|
|
||||||
|
|
||||||
//*@name active state change animation
|
|
||||||
//@{
|
|
||||||
void setOpacity( qreal );
|
|
||||||
|
|
||||||
qreal opacity() const
|
|
||||||
{ return m_opacity; }
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//*@name colors
|
|
||||||
//@{
|
|
||||||
QColor titleBarColor() const;
|
|
||||||
QColor outlineColor() const;
|
|
||||||
QColor fontColor() const;
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//*@name maximization modes
|
|
||||||
//@{
|
|
||||||
inline bool isMaximized() const;
|
|
||||||
inline bool isMaximizedHorizontally() const;
|
|
||||||
inline bool isMaximizedVertically() const;
|
|
||||||
|
|
||||||
inline bool isLeftEdge() const;
|
|
||||||
inline bool isRightEdge() const;
|
|
||||||
inline bool isTopEdge() const;
|
|
||||||
inline bool isBottomEdge() const;
|
|
||||||
|
|
||||||
inline bool hideTitleBar() const;
|
|
||||||
//@}
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
void init() override;
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void reconfigure();
|
|
||||||
void recalculateBorders();
|
|
||||||
void updateButtonsGeometry();
|
|
||||||
void updateButtonsGeometryDelayed();
|
|
||||||
void updateTitleBar();
|
|
||||||
void updateAnimationState();
|
|
||||||
void updateSizeGripVisibility();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//* return the rect in which caption will be drawn
|
|
||||||
QPair<QRect,Qt::Alignment> captionRect() const;
|
|
||||||
|
|
||||||
void createButtons();
|
|
||||||
void paintTitleBar(QPainter *painter, const QRect &repaintRegion);
|
|
||||||
void updateShadow();
|
|
||||||
static QSharedPointer<KDecoration2::DecorationShadow> createShadowObject(const InternalSettingsPtr& internalSettings, const float strengthScale, const int scale);
|
|
||||||
|
|
||||||
//*@name border size
|
|
||||||
//@{
|
|
||||||
int borderSize(bool bottom = false) const;
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//*@name size grip
|
|
||||||
//@{
|
|
||||||
void createSizeGrip();
|
|
||||||
void deleteSizeGrip();
|
|
||||||
SizeGrip* sizeGrip() const
|
|
||||||
{ return m_sizeGrip; }
|
|
||||||
//@}
|
|
||||||
|
|
||||||
InternalSettingsPtr m_internalSettings;
|
|
||||||
KDecoration2::DecorationButtonGroup *m_leftButtons = nullptr;
|
|
||||||
KDecoration2::DecorationButtonGroup *m_rightButtons = nullptr;
|
|
||||||
|
|
||||||
//* size grip widget
|
|
||||||
SizeGrip *m_sizeGrip = nullptr;
|
|
||||||
|
|
||||||
//* active state change animation
|
|
||||||
QVariantAnimation *m_animation;
|
|
||||||
QVariantAnimation *m_shadowAnimation;
|
|
||||||
|
|
||||||
//* active state change opacity
|
|
||||||
qreal m_opacity = 0;
|
|
||||||
qreal m_shadowOpacity = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
bool Decoration::isMaximized() const
|
|
||||||
{ return client().data()->isMaximized() && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
|
||||||
|
|
||||||
bool Decoration::isMaximizedHorizontally() const
|
|
||||||
{ return client().data()->isMaximizedHorizontally() && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
|
||||||
|
|
||||||
bool Decoration::isMaximizedVertically() const
|
|
||||||
{ return client().data()->isMaximizedVertically() && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
|
||||||
|
|
||||||
bool Decoration::isLeftEdge() const
|
|
||||||
{ return (client().data()->isMaximizedHorizontally() || client().data()->adjacentScreenEdges().testFlag( Qt::LeftEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
|
||||||
|
|
||||||
bool Decoration::isRightEdge() const
|
|
||||||
{ return (client().data()->isMaximizedHorizontally() || client().data()->adjacentScreenEdges().testFlag( Qt::RightEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
|
||||||
|
|
||||||
bool Decoration::isTopEdge() const
|
|
||||||
{ return (client().data()->isMaximizedVertically() || client().data()->adjacentScreenEdges().testFlag( Qt::TopEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
|
||||||
|
|
||||||
bool Decoration::isBottomEdge() const
|
|
||||||
{ return (client().data()->isMaximizedVertically() || client().data()->adjacentScreenEdges().testFlag( Qt::BottomEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
|
||||||
|
|
||||||
bool Decoration::hideTitleBar() const
|
|
||||||
{ return m_internalSettings->hideTitleBar() && !client().data()->isShaded(); }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// breezeexceptionlist.cpp
|
|
||||||
// window decoration exceptions
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "breezeexceptionlist.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//______________________________________________________________
|
|
||||||
void ExceptionList::readConfig( KSharedConfig::Ptr config )
|
|
||||||
{
|
|
||||||
|
|
||||||
_exceptions.clear();
|
|
||||||
|
|
||||||
QString groupName;
|
|
||||||
for( int index = 0; config->hasGroup( groupName = exceptionGroupName( index ) ); ++index )
|
|
||||||
{
|
|
||||||
|
|
||||||
// create exception
|
|
||||||
InternalSettings exception;
|
|
||||||
|
|
||||||
// reset group
|
|
||||||
readConfig( &exception, config.data(), groupName );
|
|
||||||
|
|
||||||
// create new configuration
|
|
||||||
InternalSettingsPtr configuration( new InternalSettings() );
|
|
||||||
configuration.data()->load();
|
|
||||||
|
|
||||||
// apply changes from exception
|
|
||||||
configuration->setEnabled( exception.enabled() );
|
|
||||||
configuration->setExceptionType( exception.exceptionType() );
|
|
||||||
configuration->setExceptionPattern( exception.exceptionPattern() );
|
|
||||||
configuration->setMask( exception.mask() );
|
|
||||||
|
|
||||||
// propagate all features found in mask to the output configuration
|
|
||||||
if( exception.mask() & BorderSize ) configuration->setBorderSize( exception.borderSize() );
|
|
||||||
configuration->setHideTitleBar( exception.hideTitleBar() );
|
|
||||||
|
|
||||||
// append to exceptions
|
|
||||||
_exceptions.append( configuration );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//______________________________________________________________
|
|
||||||
void ExceptionList::writeConfig( KSharedConfig::Ptr config )
|
|
||||||
{
|
|
||||||
|
|
||||||
// remove all existing exceptions
|
|
||||||
QString groupName;
|
|
||||||
for( int index = 0; config->hasGroup( groupName = exceptionGroupName( index ) ); ++index )
|
|
||||||
{ config->deleteGroup( groupName ); }
|
|
||||||
|
|
||||||
// rewrite current exceptions
|
|
||||||
int index = 0;
|
|
||||||
foreach( const InternalSettingsPtr& exception, _exceptions )
|
|
||||||
{
|
|
||||||
|
|
||||||
writeConfig( exception.data(), config.data(), exceptionGroupName( index ) );
|
|
||||||
++index;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________________________________
|
|
||||||
QString ExceptionList::exceptionGroupName( int index )
|
|
||||||
{ return QString( "Windeco Exception %1" ).arg( index ); }
|
|
||||||
|
|
||||||
//______________________________________________________________
|
|
||||||
void ExceptionList::writeConfig( KCoreConfigSkeleton* skeleton, KConfig* config, const QString& groupName )
|
|
||||||
{
|
|
||||||
|
|
||||||
// list of items to be written
|
|
||||||
QStringList keys = { "Enabled", "ExceptionPattern", "ExceptionType", "HideTitleBar", "Mask", "BorderSize"};
|
|
||||||
|
|
||||||
// write all items
|
|
||||||
foreach( auto key, keys )
|
|
||||||
{
|
|
||||||
KConfigSkeletonItem* item( skeleton->findItem( key ) );
|
|
||||||
if( !item ) continue;
|
|
||||||
|
|
||||||
if( !groupName.isEmpty() ) item->setGroup( groupName );
|
|
||||||
KConfigGroup configGroup( config, item->group() );
|
|
||||||
configGroup.writeEntry( item->key(), item->property() );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//______________________________________________________________
|
|
||||||
void ExceptionList::readConfig( KCoreConfigSkeleton* skeleton, KConfig* config, const QString& groupName )
|
|
||||||
{
|
|
||||||
|
|
||||||
foreach( KConfigSkeletonItem* item, skeleton->items() )
|
|
||||||
{
|
|
||||||
if( !groupName.isEmpty() ) item->setGroup( groupName );
|
|
||||||
item->readConfig( config );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
#ifndef breezeexceptionlist_h
|
|
||||||
#define breezeexceptionlist_h
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// breezeexceptionlist.h
|
|
||||||
// window decoration exceptions
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "breezesettings.h"
|
|
||||||
#include "breeze.h"
|
|
||||||
|
|
||||||
#include <KSharedConfig>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//! breeze exceptions list
|
|
||||||
class ExceptionList
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! constructor from list
|
|
||||||
explicit ExceptionList( const InternalSettingsList& exceptions = InternalSettingsList() ):
|
|
||||||
_exceptions( exceptions )
|
|
||||||
{}
|
|
||||||
|
|
||||||
//! exceptions
|
|
||||||
const InternalSettingsList& get( void ) const
|
|
||||||
{ return _exceptions; }
|
|
||||||
|
|
||||||
//! read from KConfig
|
|
||||||
void readConfig( KSharedConfig::Ptr );
|
|
||||||
|
|
||||||
//! write to kconfig
|
|
||||||
void writeConfig( KSharedConfig::Ptr );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//! generate exception group name for given exception index
|
|
||||||
static QString exceptionGroupName( int index );
|
|
||||||
|
|
||||||
//! read configuration
|
|
||||||
static void readConfig( KCoreConfigSkeleton*, KConfig*, const QString& );
|
|
||||||
|
|
||||||
//! write configuration
|
|
||||||
static void writeConfig( KCoreConfigSkeleton*, KConfig*, const QString& );
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//! exceptions
|
|
||||||
InternalSettingsList _exceptions;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
File=breezesettingsdata.kcfg
|
|
||||||
ClassName=InternalSettings
|
|
||||||
NameSpace=Breeze
|
|
||||||
Singleton=false
|
|
||||||
Mutators=true
|
|
||||||
GlobalEnums=true
|
|
||||||
Notifiers=OutlineCloseButton
|
|
||||||
@ -1,117 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
|
||||||
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
|
||||||
<kcfgfile name="breezerc"/>
|
|
||||||
|
|
||||||
<!-- common options -->
|
|
||||||
<group name="Common">
|
|
||||||
|
|
||||||
<entry name="ShadowStrength" type = "Int">
|
|
||||||
<default>255</default>
|
|
||||||
<min>25</min>
|
|
||||||
<max>255</max>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
<!-- shadow -->
|
|
||||||
<entry name="ShadowSize" type = "Enum">
|
|
||||||
<choices>
|
|
||||||
<choice name="ShadowNone"/>
|
|
||||||
<choice name="ShadowSmall"/>
|
|
||||||
<choice name="ShadowMedium"/>
|
|
||||||
<choice name="ShadowLarge"/>
|
|
||||||
<choice name="ShadowVeryLarge"/>
|
|
||||||
</choices>
|
|
||||||
<default>ShadowLarge</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
<entry name="ShadowColor" type = "Color">
|
|
||||||
<default>0, 0, 0</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
<!-- close button -->
|
|
||||||
<entry name="OutlineCloseButton" type = "Bool">
|
|
||||||
<default>true</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
</group>
|
|
||||||
|
|
||||||
<group name="Windeco">
|
|
||||||
|
|
||||||
<!-- border size -->
|
|
||||||
<!--
|
|
||||||
this one is used only for window specific settings, since the default is globally set by kwin
|
|
||||||
the enumeration must be kept in sync with kwin's global settings
|
|
||||||
-->
|
|
||||||
<entry name="BorderSize" type = "Enum"></entry>
|
|
||||||
|
|
||||||
<!-- title alignment -->
|
|
||||||
<entry name="TitleAlignment" type="Enum">
|
|
||||||
<choices>
|
|
||||||
<choice name="AlignLeft" />
|
|
||||||
<choice name="AlignCenter" />
|
|
||||||
<choice name="AlignCenterFullWidth" />
|
|
||||||
<choice name="AlignRight" />
|
|
||||||
</choices>
|
|
||||||
<default>AlignCenterFullWidth</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
<!-- button size -->
|
|
||||||
<entry name="ButtonSize" type="Enum">
|
|
||||||
<choices>
|
|
||||||
<choice name="ButtonTiny" />
|
|
||||||
<choice name="ButtonSmall" />
|
|
||||||
<choice name="ButtonDefault" />
|
|
||||||
<choice name="ButtonLarge" />
|
|
||||||
<choice name="ButtonVeryLarge" />
|
|
||||||
</choices>
|
|
||||||
<default>ButtonDefault</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
<!-- maximized windows -->
|
|
||||||
<entry name="DrawBorderOnMaximizedWindows" type = "Bool">
|
|
||||||
<default>false</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
<entry name="DrawTitleBarSeparator" type = "Bool">
|
|
||||||
<default>false</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
<!-- size grip -->
|
|
||||||
<entry name="DrawBackgroundGradient" type = "Bool">
|
|
||||||
<default>false</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
<!-- size grip -->
|
|
||||||
<entry name="DrawSizeGrip" type = "Bool">
|
|
||||||
<default>false</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
<!-- hide title bar -->
|
|
||||||
<entry name="HideTitleBar" type = "Bool">
|
|
||||||
<default>false</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
<!-- window specific settings -->
|
|
||||||
<entry name="ExceptionType" type="Enum">
|
|
||||||
<choices>
|
|
||||||
<choice name="ExceptionWindowClassName" />
|
|
||||||
<choice name="ExceptionWindowTitle" />
|
|
||||||
</choices>
|
|
||||||
<default>ExceptionWindowClassName</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
<entry name="ExceptionPattern" type = "String"/>
|
|
||||||
|
|
||||||
<entry name="Enabled" type = "Bool">
|
|
||||||
<default>true</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
<entry name="Mask" type = "Int">
|
|
||||||
<default>0</default>
|
|
||||||
</entry>
|
|
||||||
|
|
||||||
</group>
|
|
||||||
|
|
||||||
</kcfg>
|
|
||||||
@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "breezesettingsprovider.h"
|
|
||||||
|
|
||||||
#include "breezeexceptionlist.h"
|
|
||||||
|
|
||||||
#include <KWindowInfo>
|
|
||||||
|
|
||||||
#include <QTextStream>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
SettingsProvider *SettingsProvider::s_self = nullptr;
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
SettingsProvider::SettingsProvider():
|
|
||||||
m_config( KSharedConfig::openConfig( QStringLiteral("breezerc") ) )
|
|
||||||
{ reconfigure(); }
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
SettingsProvider::~SettingsProvider()
|
|
||||||
{ s_self = nullptr; }
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
SettingsProvider *SettingsProvider::self()
|
|
||||||
{
|
|
||||||
// TODO: this is not thread safe!
|
|
||||||
if (!s_self)
|
|
||||||
{ s_self = new SettingsProvider(); }
|
|
||||||
|
|
||||||
return s_self;
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
void SettingsProvider::reconfigure()
|
|
||||||
{
|
|
||||||
if( !m_defaultSettings )
|
|
||||||
{
|
|
||||||
m_defaultSettings = InternalSettingsPtr(new InternalSettings());
|
|
||||||
m_defaultSettings->setCurrentGroup( QStringLiteral("Windeco") );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_defaultSettings->load();
|
|
||||||
|
|
||||||
ExceptionList exceptions;
|
|
||||||
exceptions.readConfig( m_config );
|
|
||||||
m_exceptions = exceptions.get();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
InternalSettingsPtr SettingsProvider::internalSettings( Decoration *decoration ) const
|
|
||||||
{
|
|
||||||
|
|
||||||
QString windowTitle;
|
|
||||||
QString className;
|
|
||||||
|
|
||||||
// get the client
|
|
||||||
auto client = decoration->client().data();
|
|
||||||
|
|
||||||
foreach( auto internalSettings, m_exceptions )
|
|
||||||
{
|
|
||||||
|
|
||||||
// discard disabled exceptions
|
|
||||||
if( !internalSettings->enabled() ) continue;
|
|
||||||
|
|
||||||
// discard exceptions with empty exception pattern
|
|
||||||
if( internalSettings->exceptionPattern().isEmpty() ) continue;
|
|
||||||
|
|
||||||
/*
|
|
||||||
decide which value is to be compared
|
|
||||||
to the regular expression, based on exception type
|
|
||||||
*/
|
|
||||||
QString value;
|
|
||||||
switch( internalSettings->exceptionType() )
|
|
||||||
{
|
|
||||||
case InternalSettings::ExceptionWindowTitle:
|
|
||||||
{
|
|
||||||
value = windowTitle.isEmpty() ? (windowTitle = client->caption()):windowTitle;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
case InternalSettings::ExceptionWindowClassName:
|
|
||||||
{
|
|
||||||
if( className.isEmpty() )
|
|
||||||
{
|
|
||||||
// retrieve class name
|
|
||||||
KWindowInfo info( client->windowId(), nullptr, NET::WM2WindowClass );
|
|
||||||
QString window_className( QString::fromUtf8(info.windowClassName()) );
|
|
||||||
QString window_class( QString::fromUtf8(info.windowClassClass()) );
|
|
||||||
className = window_className + QStringLiteral(" ") + window_class;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = className;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// check matching
|
|
||||||
if( QRegExp( internalSettings->exceptionPattern() ).indexIn( value ) >= 0 )
|
|
||||||
{ return internalSettings; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_defaultSettings;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
#ifndef breezesettingsprovider_h
|
|
||||||
#define breezesettingsprovider_h
|
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "breezedecoration.h"
|
|
||||||
#include "breezesettings.h"
|
|
||||||
#include "breeze.h"
|
|
||||||
|
|
||||||
#include <KSharedConfig>
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
class SettingsProvider: public QObject
|
|
||||||
{
|
|
||||||
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//* destructor
|
|
||||||
~SettingsProvider();
|
|
||||||
|
|
||||||
//* singleton
|
|
||||||
static SettingsProvider *self();
|
|
||||||
|
|
||||||
//* internal settings for given decoration
|
|
||||||
InternalSettingsPtr internalSettings(Decoration *) const;
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
|
|
||||||
//* reconfigure
|
|
||||||
void reconfigure();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//* constructor
|
|
||||||
SettingsProvider();
|
|
||||||
|
|
||||||
//* default configuration
|
|
||||||
InternalSettingsPtr m_defaultSettings;
|
|
||||||
|
|
||||||
//* exceptions
|
|
||||||
InternalSettingsList m_exceptions;
|
|
||||||
|
|
||||||
//* config object
|
|
||||||
KSharedConfigPtr m_config;
|
|
||||||
|
|
||||||
//* singleton
|
|
||||||
static SettingsProvider *s_self;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,290 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "breezesizegrip.h"
|
|
||||||
|
|
||||||
#include <KDecoration2/DecoratedClient>
|
|
||||||
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QPolygon>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
#include <QX11Info>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//* scoped pointer convenience typedef
|
|
||||||
template <typename T> using ScopedPointer = QScopedPointer<T, QScopedPointerPodDeleter>;
|
|
||||||
|
|
||||||
//_____________________________________________
|
|
||||||
SizeGrip::SizeGrip( Decoration* decoration ):QWidget(nullptr)
|
|
||||||
,m_decoration( decoration )
|
|
||||||
{
|
|
||||||
|
|
||||||
setAttribute(Qt::WA_NoSystemBackground );
|
|
||||||
setAutoFillBackground( false );
|
|
||||||
|
|
||||||
// cursor
|
|
||||||
setCursor( Qt::SizeFDiagCursor );
|
|
||||||
|
|
||||||
// size
|
|
||||||
setFixedSize( QSize( GripSize, GripSize ) );
|
|
||||||
|
|
||||||
// mask
|
|
||||||
setMask( QRegion( QVector<QPoint>{
|
|
||||||
QPoint( 0, GripSize ),
|
|
||||||
QPoint( GripSize, 0 ),
|
|
||||||
QPoint( GripSize, GripSize ),
|
|
||||||
QPoint( 0, GripSize )} ) );
|
|
||||||
|
|
||||||
// embed
|
|
||||||
embed();
|
|
||||||
updatePosition();
|
|
||||||
|
|
||||||
// connections
|
|
||||||
auto c = decoration->client().data();
|
|
||||||
connect( c, &KDecoration2::DecoratedClient::widthChanged, this, &SizeGrip::updatePosition );
|
|
||||||
connect( c, &KDecoration2::DecoratedClient::heightChanged, this, &SizeGrip::updatePosition );
|
|
||||||
connect( c, &KDecoration2::DecoratedClient::activeChanged, this, &SizeGrip::updateActiveState );
|
|
||||||
|
|
||||||
// show
|
|
||||||
show();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_____________________________________________
|
|
||||||
SizeGrip::~SizeGrip()
|
|
||||||
{}
|
|
||||||
|
|
||||||
//_____________________________________________
|
|
||||||
void SizeGrip::updateActiveState()
|
|
||||||
{
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
if( QX11Info::isPlatformX11() )
|
|
||||||
{
|
|
||||||
const quint32 value = XCB_STACK_MODE_ABOVE;
|
|
||||||
xcb_configure_window( QX11Info::connection(), winId(), XCB_CONFIG_WINDOW_STACK_MODE, &value );
|
|
||||||
xcb_map_window( QX11Info::connection(), winId() );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
update();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_____________________________________________
|
|
||||||
void SizeGrip::embed()
|
|
||||||
{
|
|
||||||
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
|
|
||||||
if( !QX11Info::isPlatformX11() ) return;
|
|
||||||
auto c = m_decoration.data()->client().data();
|
|
||||||
|
|
||||||
xcb_window_t windowId = c->windowId();
|
|
||||||
if( windowId )
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
find client's parent
|
|
||||||
we want the size grip to be at the same level as the client in the stack
|
|
||||||
*/
|
|
||||||
xcb_window_t current = windowId;
|
|
||||||
auto connection = QX11Info::connection();
|
|
||||||
xcb_query_tree_cookie_t cookie = xcb_query_tree_unchecked( connection, current );
|
|
||||||
ScopedPointer<xcb_query_tree_reply_t> tree(xcb_query_tree_reply( connection, cookie, nullptr ) );
|
|
||||||
if( !tree.isNull() && tree->parent ) current = tree->parent;
|
|
||||||
|
|
||||||
// reparent
|
|
||||||
xcb_reparent_window( connection, winId(), current, 0, 0 );
|
|
||||||
setWindowTitle( "Breeze::SizeGrip" );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
hide();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//_____________________________________________
|
|
||||||
void SizeGrip::paintEvent( QPaintEvent* )
|
|
||||||
{
|
|
||||||
|
|
||||||
if( !m_decoration ) return;
|
|
||||||
|
|
||||||
// get relevant colors
|
|
||||||
const QColor backgroundColor( m_decoration.data()->titleBarColor() );
|
|
||||||
|
|
||||||
// create and configure painter
|
|
||||||
QPainter painter(this);
|
|
||||||
painter.setRenderHints(QPainter::Antialiasing );
|
|
||||||
|
|
||||||
painter.setPen( Qt::NoPen );
|
|
||||||
painter.setBrush( backgroundColor );
|
|
||||||
|
|
||||||
// polygon
|
|
||||||
painter.drawPolygon( QVector<QPoint> {
|
|
||||||
QPoint( 0, GripSize ),
|
|
||||||
QPoint( GripSize, 0 ),
|
|
||||||
QPoint( GripSize, GripSize ),
|
|
||||||
QPoint( 0, GripSize )} );
|
|
||||||
}
|
|
||||||
|
|
||||||
//_____________________________________________
|
|
||||||
void SizeGrip::mousePressEvent( QMouseEvent* event )
|
|
||||||
{
|
|
||||||
|
|
||||||
switch (event->button())
|
|
||||||
{
|
|
||||||
|
|
||||||
case Qt::RightButton:
|
|
||||||
{
|
|
||||||
hide();
|
|
||||||
QTimer::singleShot(5000, this, &QWidget::show);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Qt::MiddleButton:
|
|
||||||
{
|
|
||||||
hide();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Qt::LeftButton:
|
|
||||||
if( rect().contains( event->pos() ) )
|
|
||||||
{ sendMoveResizeEvent( event->pos() ); }
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________________________________________
|
|
||||||
void SizeGrip::updatePosition()
|
|
||||||
{
|
|
||||||
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
if( !QX11Info::isPlatformX11() ) return;
|
|
||||||
|
|
||||||
auto c = m_decoration.data()->client().data();
|
|
||||||
QPoint position(
|
|
||||||
c->width() - GripSize - Offset,
|
|
||||||
c->height() - GripSize - Offset );
|
|
||||||
|
|
||||||
quint32 values[2] = { quint32(position.x()), quint32(position.y()) };
|
|
||||||
xcb_configure_window( QX11Info::connection(), winId(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_____________________________________________
|
|
||||||
void SizeGrip::sendMoveResizeEvent( QPoint position )
|
|
||||||
{
|
|
||||||
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
if( !QX11Info::isPlatformX11() ) return;
|
|
||||||
|
|
||||||
// pointer to connection
|
|
||||||
auto connection( QX11Info::connection() );
|
|
||||||
|
|
||||||
// client
|
|
||||||
auto c = m_decoration.data()->client().data();
|
|
||||||
|
|
||||||
/*
|
|
||||||
get root position matching position
|
|
||||||
need to use xcb because the embedding of the widget
|
|
||||||
breaks QT's mapToGlobal and other methods
|
|
||||||
*/
|
|
||||||
QPoint rootPosition( position );
|
|
||||||
xcb_get_geometry_cookie_t cookie( xcb_get_geometry( connection, winId() ) );
|
|
||||||
ScopedPointer<xcb_get_geometry_reply_t> reply( xcb_get_geometry_reply( connection, cookie, nullptr ) );
|
|
||||||
if( reply )
|
|
||||||
{
|
|
||||||
|
|
||||||
// translate coordinates
|
|
||||||
xcb_translate_coordinates_cookie_t coordCookie( xcb_translate_coordinates(
|
|
||||||
connection, winId(), reply.data()->root,
|
|
||||||
-reply.data()->border_width,
|
|
||||||
-reply.data()->border_width ) );
|
|
||||||
|
|
||||||
ScopedPointer< xcb_translate_coordinates_reply_t> coordReply( xcb_translate_coordinates_reply( connection, coordCookie, nullptr ) );
|
|
||||||
|
|
||||||
if( coordReply )
|
|
||||||
{
|
|
||||||
rootPosition.rx() += coordReply.data()->dst_x;
|
|
||||||
rootPosition.ry() += coordReply.data()->dst_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// move/resize atom
|
|
||||||
if( !m_moveResizeAtom )
|
|
||||||
{
|
|
||||||
|
|
||||||
// create atom if not found
|
|
||||||
const QString atomName( "_NET_WM_MOVERESIZE" );
|
|
||||||
xcb_intern_atom_cookie_t cookie( xcb_intern_atom( connection, false, atomName.size(), qPrintable( atomName ) ) );
|
|
||||||
ScopedPointer<xcb_intern_atom_reply_t> reply( xcb_intern_atom_reply( connection, cookie, nullptr ) );
|
|
||||||
m_moveResizeAtom = reply ? reply->atom:0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !m_moveResizeAtom ) return;
|
|
||||||
|
|
||||||
// button release event
|
|
||||||
xcb_button_release_event_t releaseEvent;
|
|
||||||
memset(&releaseEvent, 0, sizeof(releaseEvent));
|
|
||||||
|
|
||||||
releaseEvent.response_type = XCB_BUTTON_RELEASE;
|
|
||||||
releaseEvent.event = winId();
|
|
||||||
releaseEvent.child = XCB_WINDOW_NONE;
|
|
||||||
releaseEvent.root = QX11Info::appRootWindow();
|
|
||||||
releaseEvent.event_x = position.x();
|
|
||||||
releaseEvent.event_y = position.y();
|
|
||||||
releaseEvent.root_x = rootPosition.x();
|
|
||||||
releaseEvent.root_y = rootPosition.y();
|
|
||||||
releaseEvent.detail = XCB_BUTTON_INDEX_1;
|
|
||||||
releaseEvent.state = XCB_BUTTON_MASK_1;
|
|
||||||
releaseEvent.time = XCB_CURRENT_TIME;
|
|
||||||
releaseEvent.same_screen = true;
|
|
||||||
xcb_send_event( connection, false, winId(), XCB_EVENT_MASK_BUTTON_RELEASE, reinterpret_cast<const char*>(&releaseEvent));
|
|
||||||
|
|
||||||
xcb_ungrab_pointer( connection, XCB_TIME_CURRENT_TIME );
|
|
||||||
|
|
||||||
// move resize event
|
|
||||||
xcb_client_message_event_t clientMessageEvent;
|
|
||||||
memset(&clientMessageEvent, 0, sizeof(clientMessageEvent));
|
|
||||||
|
|
||||||
clientMessageEvent.response_type = XCB_CLIENT_MESSAGE;
|
|
||||||
clientMessageEvent.type = m_moveResizeAtom;
|
|
||||||
clientMessageEvent.format = 32;
|
|
||||||
clientMessageEvent.window = c->windowId();
|
|
||||||
clientMessageEvent.data.data32[0] = rootPosition.x();
|
|
||||||
clientMessageEvent.data.data32[1] = rootPosition.y();
|
|
||||||
clientMessageEvent.data.data32[2] = 4; // bottom right
|
|
||||||
clientMessageEvent.data.data32[3] = Qt::LeftButton;
|
|
||||||
clientMessageEvent.data.data32[4] = 0;
|
|
||||||
|
|
||||||
xcb_send_event( connection, false, QX11Info::appRootWindow(),
|
|
||||||
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
|
|
||||||
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
|
|
||||||
reinterpret_cast<const char*>(&clientMessageEvent) );
|
|
||||||
|
|
||||||
xcb_flush( connection );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef breezesizegrip_h
|
|
||||||
#define breezesizegrip_h
|
|
||||||
|
|
||||||
#include "breezedecoration.h"
|
|
||||||
#include "config-breeze.h"
|
|
||||||
|
|
||||||
#include <QMouseEvent>
|
|
||||||
#include <QPaintEvent>
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QPointer>
|
|
||||||
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
#include <xcb/xcb.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//* implements size grip for all widgets
|
|
||||||
class SizeGrip: public QWidget
|
|
||||||
{
|
|
||||||
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//* constructor
|
|
||||||
explicit SizeGrip( Decoration* );
|
|
||||||
|
|
||||||
//* constructor
|
|
||||||
virtual ~SizeGrip();
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
|
|
||||||
//* update background color
|
|
||||||
void updateActiveState();
|
|
||||||
|
|
||||||
//* update position
|
|
||||||
void updatePosition();
|
|
||||||
|
|
||||||
//* embed into parent widget
|
|
||||||
void embed();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//*@name event handlers
|
|
||||||
//@{
|
|
||||||
|
|
||||||
//* paint
|
|
||||||
virtual void paintEvent( QPaintEvent* ) override;
|
|
||||||
|
|
||||||
//* mouse press
|
|
||||||
virtual void mousePressEvent( QMouseEvent* ) override;
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//* send resize event
|
|
||||||
void sendMoveResizeEvent( QPoint );
|
|
||||||
|
|
||||||
//* grip size
|
|
||||||
enum {
|
|
||||||
Offset = 0,
|
|
||||||
GripSize = 14
|
|
||||||
};
|
|
||||||
|
|
||||||
//* decoration
|
|
||||||
QPointer<Decoration> m_decoration;
|
|
||||||
|
|
||||||
//* move/resize atom
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
xcb_atom_t m_moveResizeAtom = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
/* config-breeze.h. Generated by cmake from config-breeze.h.cmake */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef config_breeze_h
|
|
||||||
#define config_breeze_h
|
|
||||||
|
|
||||||
/* Define to 1 if XCB libraries are found */
|
|
||||||
#cmakedefine01 BREEZE_HAVE_X11
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,187 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// breezeconfigurationui.cpp
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "breezeconfigwidget.h"
|
|
||||||
#include "breezeexceptionlist.h"
|
|
||||||
|
|
||||||
#include <KLocalizedString>
|
|
||||||
|
|
||||||
#include <QDBusConnection>
|
|
||||||
#include <QDBusMessage>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//_________________________________________________________
|
|
||||||
ConfigWidget::ConfigWidget( QWidget* parent, const QVariantList &args ):
|
|
||||||
KCModule(parent, args),
|
|
||||||
m_configuration( KSharedConfig::openConfig( QStringLiteral( "breezerc" ) ) ),
|
|
||||||
m_changed( false )
|
|
||||||
{
|
|
||||||
|
|
||||||
// configuration
|
|
||||||
m_ui.setupUi( this );
|
|
||||||
|
|
||||||
// track ui changes
|
|
||||||
connect( m_ui.titleAlignment, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) );
|
|
||||||
connect( m_ui.buttonSize, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) );
|
|
||||||
connect( m_ui.outlineCloseButton, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged );
|
|
||||||
connect( m_ui.drawBorderOnMaximizedWindows, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged );
|
|
||||||
connect( m_ui.drawSizeGrip, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged );
|
|
||||||
connect( m_ui.drawBackgroundGradient, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged );
|
|
||||||
connect( m_ui.drawTitleBarSeparator, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged );
|
|
||||||
|
|
||||||
// track shadows changes
|
|
||||||
connect( m_ui.shadowSize, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) );
|
|
||||||
connect( m_ui.shadowStrength, SIGNAL(valueChanged(int)), SLOT(updateChanged()) );
|
|
||||||
connect( m_ui.shadowColor, &KColorButton::changed, this, &ConfigWidget::updateChanged );
|
|
||||||
|
|
||||||
// track exception changes
|
|
||||||
connect( m_ui.exceptions, &ExceptionListWidget::changed, this, &ConfigWidget::updateChanged );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_________________________________________________________
|
|
||||||
void ConfigWidget::load()
|
|
||||||
{
|
|
||||||
|
|
||||||
// create internal settings and load from rc files
|
|
||||||
m_internalSettings = InternalSettingsPtr( new InternalSettings() );
|
|
||||||
m_internalSettings->load();
|
|
||||||
|
|
||||||
// assign to ui
|
|
||||||
m_ui.titleAlignment->setCurrentIndex( m_internalSettings->titleAlignment() );
|
|
||||||
m_ui.buttonSize->setCurrentIndex( m_internalSettings->buttonSize() );
|
|
||||||
m_ui.drawBorderOnMaximizedWindows->setChecked( m_internalSettings->drawBorderOnMaximizedWindows() );
|
|
||||||
m_ui.outlineCloseButton->setChecked( m_internalSettings->outlineCloseButton() );
|
|
||||||
m_ui.drawSizeGrip->setChecked( m_internalSettings->drawSizeGrip() );
|
|
||||||
m_ui.drawBackgroundGradient->setChecked( m_internalSettings->drawBackgroundGradient() );
|
|
||||||
m_ui.drawTitleBarSeparator->setChecked( m_internalSettings->drawTitleBarSeparator() );
|
|
||||||
|
|
||||||
// load shadows
|
|
||||||
if( m_internalSettings->shadowSize() <= InternalSettings::ShadowVeryLarge ) m_ui.shadowSize->setCurrentIndex( m_internalSettings->shadowSize() );
|
|
||||||
else m_ui.shadowSize->setCurrentIndex( InternalSettings::ShadowLarge );
|
|
||||||
|
|
||||||
m_ui.shadowStrength->setValue( qRound(qreal(m_internalSettings->shadowStrength()*100)/255 ) );
|
|
||||||
m_ui.shadowColor->setColor( m_internalSettings->shadowColor() );
|
|
||||||
|
|
||||||
// load exceptions
|
|
||||||
ExceptionList exceptions;
|
|
||||||
exceptions.readConfig( m_configuration );
|
|
||||||
m_ui.exceptions->setExceptions( exceptions.get() );
|
|
||||||
setChanged( false );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_________________________________________________________
|
|
||||||
void ConfigWidget::save()
|
|
||||||
{
|
|
||||||
|
|
||||||
// create internal settings and load from rc files
|
|
||||||
m_internalSettings = InternalSettingsPtr( new InternalSettings() );
|
|
||||||
m_internalSettings->load();
|
|
||||||
|
|
||||||
// apply modifications from ui
|
|
||||||
m_internalSettings->setTitleAlignment( m_ui.titleAlignment->currentIndex() );
|
|
||||||
m_internalSettings->setButtonSize( m_ui.buttonSize->currentIndex() );
|
|
||||||
m_internalSettings->setOutlineCloseButton( m_ui.outlineCloseButton->isChecked() );
|
|
||||||
m_internalSettings->setDrawBorderOnMaximizedWindows( m_ui.drawBorderOnMaximizedWindows->isChecked() );
|
|
||||||
m_internalSettings->setDrawSizeGrip( m_ui.drawSizeGrip->isChecked() );
|
|
||||||
m_internalSettings->setDrawBackgroundGradient( m_ui.drawBackgroundGradient->isChecked() );
|
|
||||||
m_internalSettings->setDrawTitleBarSeparator(m_ui.drawTitleBarSeparator->isChecked());
|
|
||||||
|
|
||||||
m_internalSettings->setShadowSize( m_ui.shadowSize->currentIndex() );
|
|
||||||
m_internalSettings->setShadowStrength( qRound( qreal(m_ui.shadowStrength->value()*255)/100 ) );
|
|
||||||
m_internalSettings->setShadowColor( m_ui.shadowColor->color() );
|
|
||||||
|
|
||||||
// save configuration
|
|
||||||
m_internalSettings->save();
|
|
||||||
|
|
||||||
// get list of exceptions and write
|
|
||||||
InternalSettingsList exceptions( m_ui.exceptions->exceptions() );
|
|
||||||
ExceptionList( exceptions ).writeConfig( m_configuration );
|
|
||||||
|
|
||||||
// sync configuration
|
|
||||||
m_configuration->sync();
|
|
||||||
setChanged( false );
|
|
||||||
|
|
||||||
// needed to tell kwin to reload when running from external kcmshell
|
|
||||||
{
|
|
||||||
QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
|
||||||
QDBusConnection::sessionBus().send(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// needed for breeze style to reload shadows
|
|
||||||
{
|
|
||||||
QDBusMessage message( QDBusMessage::createSignal("/BreezeDecoration", "org.kde.Breeze.Style", "reparseConfiguration") );
|
|
||||||
QDBusConnection::sessionBus().send(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_________________________________________________________
|
|
||||||
void ConfigWidget::defaults()
|
|
||||||
{
|
|
||||||
|
|
||||||
// create internal settings and load from rc files
|
|
||||||
m_internalSettings = InternalSettingsPtr( new InternalSettings() );
|
|
||||||
m_internalSettings->setDefaults();
|
|
||||||
|
|
||||||
// assign to ui
|
|
||||||
m_ui.titleAlignment->setCurrentIndex( m_internalSettings->titleAlignment() );
|
|
||||||
m_ui.buttonSize->setCurrentIndex( m_internalSettings->buttonSize() );
|
|
||||||
m_ui.outlineCloseButton->setChecked( m_internalSettings->outlineCloseButton() );
|
|
||||||
m_ui.drawBorderOnMaximizedWindows->setChecked( m_internalSettings->drawBorderOnMaximizedWindows() );
|
|
||||||
m_ui.drawSizeGrip->setChecked( m_internalSettings->drawSizeGrip() );
|
|
||||||
m_ui.drawBackgroundGradient->setChecked( m_internalSettings->drawBackgroundGradient() );
|
|
||||||
m_ui.drawTitleBarSeparator->setChecked( m_internalSettings->drawTitleBarSeparator() );
|
|
||||||
|
|
||||||
m_ui.shadowSize->setCurrentIndex( m_internalSettings->shadowSize() );
|
|
||||||
m_ui.shadowStrength->setValue( qRound(qreal(m_internalSettings->shadowStrength()*100)/255 ) );
|
|
||||||
m_ui.shadowColor->setColor( m_internalSettings->shadowColor() );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________
|
|
||||||
void ConfigWidget::updateChanged()
|
|
||||||
{
|
|
||||||
|
|
||||||
// check configuration
|
|
||||||
if( !m_internalSettings ) return;
|
|
||||||
|
|
||||||
// track modifications
|
|
||||||
bool modified( false );
|
|
||||||
|
|
||||||
if (m_ui.drawTitleBarSeparator->isChecked() != m_internalSettings->drawTitleBarSeparator()) modified = true;
|
|
||||||
if( m_ui.titleAlignment->currentIndex() != m_internalSettings->titleAlignment() ) modified = true;
|
|
||||||
else if( m_ui.buttonSize->currentIndex() != m_internalSettings->buttonSize() ) modified = true;
|
|
||||||
else if( m_ui.outlineCloseButton->isChecked() != m_internalSettings->outlineCloseButton() ) modified = true;
|
|
||||||
else if( m_ui.drawBorderOnMaximizedWindows->isChecked() != m_internalSettings->drawBorderOnMaximizedWindows() ) modified = true;
|
|
||||||
else if( m_ui.drawSizeGrip->isChecked() != m_internalSettings->drawSizeGrip() ) modified = true;
|
|
||||||
else if( m_ui.drawBackgroundGradient->isChecked() != m_internalSettings->drawBackgroundGradient() ) modified = true;
|
|
||||||
|
|
||||||
// shadows
|
|
||||||
else if( m_ui.shadowSize->currentIndex() != m_internalSettings->shadowSize() ) modified = true;
|
|
||||||
else if( qRound( qreal(m_ui.shadowStrength->value()*255)/100 ) != m_internalSettings->shadowStrength() ) modified = true;
|
|
||||||
else if( m_ui.shadowColor->color() != m_internalSettings->shadowColor() ) modified = true;
|
|
||||||
|
|
||||||
// exceptions
|
|
||||||
else if( m_ui.exceptions->isChanged() ) modified = true;
|
|
||||||
|
|
||||||
setChanged( modified );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________
|
|
||||||
void ConfigWidget::setChanged( bool value )
|
|
||||||
{
|
|
||||||
emit changed( value );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
#ifndef breezeconfigwidget_h
|
|
||||||
#define breezeconfigwidget_h
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// breezeconfigurationui.h
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "ui_breezeconfigurationui.h"
|
|
||||||
#include "breezeexceptionlistwidget.h"
|
|
||||||
#include "breezesettings.h"
|
|
||||||
#include "breeze.h"
|
|
||||||
|
|
||||||
#include <KCModule>
|
|
||||||
#include <KSharedConfig>
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QSharedPointer>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//_____________________________________________
|
|
||||||
class ConfigWidget: public KCModule
|
|
||||||
{
|
|
||||||
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//* constructor
|
|
||||||
explicit ConfigWidget( QWidget*, const QVariantList& );
|
|
||||||
|
|
||||||
//* destructor
|
|
||||||
virtual ~ConfigWidget() = default;
|
|
||||||
|
|
||||||
//* default
|
|
||||||
void defaults() override;
|
|
||||||
|
|
||||||
//* load configuration
|
|
||||||
void load() override;
|
|
||||||
|
|
||||||
//* save configuration
|
|
||||||
void save() override;
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
|
|
||||||
//* update changed state
|
|
||||||
virtual void updateChanged();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//* set changed state
|
|
||||||
void setChanged( bool );
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//* ui
|
|
||||||
Ui_BreezeConfigurationUI m_ui;
|
|
||||||
|
|
||||||
//* kconfiguration object
|
|
||||||
KSharedConfig::Ptr m_configuration;
|
|
||||||
|
|
||||||
//* internal exception
|
|
||||||
InternalSettingsPtr m_internalSettings;
|
|
||||||
|
|
||||||
//* changed state
|
|
||||||
bool m_changed;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,166 +0,0 @@
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// breezedetectwidget.cpp
|
|
||||||
// Note: this class is a stripped down version of
|
|
||||||
// /kdebase/workspace/kwin/kcmkwin/kwinrules/detectwidget.cpp
|
|
||||||
// SPDX-FileCopyrightText: 2004 Lubos Lunak <l.lunak@kde.org>
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "breezedetectwidget.h"
|
|
||||||
|
|
||||||
#include "breeze.h"
|
|
||||||
|
|
||||||
#include <KWindowInfo>
|
|
||||||
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QMouseEvent>
|
|
||||||
#include <config-breeze.h>
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
#include <QX11Info>
|
|
||||||
#include <xcb/xcb.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//_________________________________________________________
|
|
||||||
DetectDialog::DetectDialog( QWidget* parent ):
|
|
||||||
QDialog( parent )
|
|
||||||
{
|
|
||||||
|
|
||||||
// setup
|
|
||||||
m_ui.setupUi( this );
|
|
||||||
|
|
||||||
connect( m_ui.buttonBox->button( QDialogButtonBox::Cancel ), &QAbstractButton::clicked, this, &QWidget::close );
|
|
||||||
m_ui.windowClassCheckBox->setChecked( true );
|
|
||||||
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
if (QX11Info::isPlatformX11()) {
|
|
||||||
// create atom
|
|
||||||
xcb_connection_t* connection( QX11Info::connection() );
|
|
||||||
const QString atomName( QStringLiteral( "WM_STATE" ) );
|
|
||||||
xcb_intern_atom_cookie_t cookie( xcb_intern_atom( connection, false, atomName.size(), qPrintable( atomName ) ) );
|
|
||||||
QScopedPointer<xcb_intern_atom_reply_t, QScopedPointerPodDeleter> reply( xcb_intern_atom_reply( connection, cookie, nullptr) );
|
|
||||||
m_wmStateAtom = reply ? reply->atom : 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_________________________________________________________
|
|
||||||
void DetectDialog::detect( WId window )
|
|
||||||
{
|
|
||||||
if( window == 0 ) selectWindow();
|
|
||||||
else readWindow( window );
|
|
||||||
}
|
|
||||||
|
|
||||||
//_________________________________________________________
|
|
||||||
void DetectDialog::readWindow( WId window )
|
|
||||||
{
|
|
||||||
|
|
||||||
if( window == 0 )
|
|
||||||
{
|
|
||||||
emit detectionDone( false );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_info.reset(new KWindowInfo( window, NET::WMAllProperties, NET::WM2AllProperties ));
|
|
||||||
if( !m_info->valid())
|
|
||||||
{
|
|
||||||
emit detectionDone( false );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString wmClassClass( QString::fromUtf8( m_info->windowClassClass() ) );
|
|
||||||
const QString wmClassName( QString::fromUtf8( m_info->windowClassName() ) );
|
|
||||||
|
|
||||||
m_ui.windowClass->setText( QStringLiteral( "%1 (%2 %3)" ).arg( wmClassClass ).arg( wmClassName ).arg( wmClassClass ) );
|
|
||||||
m_ui.windowTitle->setText( m_info->name() );
|
|
||||||
emit detectionDone( exec() == QDialog::Accepted );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_________________________________________________________
|
|
||||||
void DetectDialog::selectWindow()
|
|
||||||
{
|
|
||||||
|
|
||||||
// use a dialog, so that all user input is blocked
|
|
||||||
// use WX11BypassWM and moving away so that it's not actually visible
|
|
||||||
// grab only mouse, so that keyboard can be used e.g. for switching windows
|
|
||||||
m_grabber = new QDialog( nullptr, Qt::X11BypassWindowManagerHint );
|
|
||||||
m_grabber->move( -1000, -1000 );
|
|
||||||
m_grabber->setModal( true );
|
|
||||||
m_grabber->show();
|
|
||||||
|
|
||||||
// need to explicitly override cursor for Qt5
|
|
||||||
qApp->setOverrideCursor( Qt::CrossCursor );
|
|
||||||
m_grabber->grabMouse( Qt::CrossCursor );
|
|
||||||
m_grabber->installEventFilter( this );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_________________________________________________________
|
|
||||||
bool DetectDialog::eventFilter( QObject* o, QEvent* e )
|
|
||||||
{
|
|
||||||
// check object and event type
|
|
||||||
if( o != m_grabber ) return false;
|
|
||||||
if( e->type() != QEvent::MouseButtonRelease ) return false;
|
|
||||||
|
|
||||||
// need to explicitly release cursor for Qt5
|
|
||||||
qApp->restoreOverrideCursor();
|
|
||||||
|
|
||||||
// delete old m_grabber
|
|
||||||
delete m_grabber;
|
|
||||||
m_grabber = nullptr;
|
|
||||||
|
|
||||||
// check button
|
|
||||||
if( static_cast< QMouseEvent* >( e )->button() != Qt::LeftButton ) return true;
|
|
||||||
|
|
||||||
// read window information
|
|
||||||
readWindow( findWindow() );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//_________________________________________________________
|
|
||||||
WId DetectDialog::findWindow()
|
|
||||||
{
|
|
||||||
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
if (!QX11Info::isPlatformX11()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// check atom
|
|
||||||
if( !m_wmStateAtom ) return 0;
|
|
||||||
|
|
||||||
xcb_connection_t* connection( QX11Info::connection() );
|
|
||||||
xcb_window_t parent( QX11Info::appRootWindow() );
|
|
||||||
|
|
||||||
// why is there a loop of only 10 here
|
|
||||||
for( int i = 0; i < 10; ++i )
|
|
||||||
{
|
|
||||||
|
|
||||||
// query pointer
|
|
||||||
xcb_query_pointer_cookie_t pointerCookie( xcb_query_pointer( connection, parent ) );
|
|
||||||
QScopedPointer<xcb_query_pointer_reply_t, QScopedPointerPodDeleter> pointerReply( xcb_query_pointer_reply( connection, pointerCookie, nullptr ) );
|
|
||||||
if( !( pointerReply && pointerReply->child ) ) return 0;
|
|
||||||
|
|
||||||
const xcb_window_t child( pointerReply->child );
|
|
||||||
xcb_get_property_cookie_t cookie( xcb_get_property( connection, 0, child, m_wmStateAtom, XCB_GET_PROPERTY_TYPE_ANY, 0, 0 ) );
|
|
||||||
QScopedPointer<xcb_get_property_reply_t, QScopedPointerPodDeleter> reply( xcb_get_property_reply( connection, cookie, nullptr ) );
|
|
||||||
if( reply && reply->type ) return child;
|
|
||||||
else parent = child;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
#ifndef breezedetectwidget_h
|
|
||||||
#define breezedetectwidget_h
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// breezedetectwidget.h
|
|
||||||
// Note: this class is a stripped down version of
|
|
||||||
// /kdebase/workspace/kwin/kcmkwin/kwinrules/detectwidget.h
|
|
||||||
// SPDX-FileCopyrightText: 2004 Lubos Lunak <l.lunak@kde.org>
|
|
||||||
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "breezesettings.h"
|
|
||||||
#include "ui_breezedetectwidget.h"
|
|
||||||
|
|
||||||
#include <QByteArray>
|
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QEvent>
|
|
||||||
#include <QLabel>
|
|
||||||
|
|
||||||
#include <kwindowsystem.h>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
class DetectDialog : public QDialog
|
|
||||||
{
|
|
||||||
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//* constructor
|
|
||||||
explicit DetectDialog( QWidget* );
|
|
||||||
|
|
||||||
//* read window properties or select one from mouse grab
|
|
||||||
void detect( WId window );
|
|
||||||
|
|
||||||
//* selected class
|
|
||||||
QByteArray selectedClass() const;
|
|
||||||
|
|
||||||
//* window information
|
|
||||||
const KWindowInfo& windowInfo() const
|
|
||||||
{ return *(m_info.data()); }
|
|
||||||
|
|
||||||
//* exception type
|
|
||||||
InternalSettings::EnumExceptionType exceptionType() const
|
|
||||||
{
|
|
||||||
if( m_ui.windowClassCheckBox->isChecked() ) return InternalSettings::ExceptionWindowClassName;
|
|
||||||
else if( m_ui.windowTitleCheckBox->isChecked() ) return InternalSettings::ExceptionWindowTitle;
|
|
||||||
else return InternalSettings::ExceptionWindowClassName;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
|
|
||||||
void detectionDone( bool );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
bool eventFilter( QObject* o, QEvent* e ) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//* select window from grab
|
|
||||||
void selectWindow();
|
|
||||||
|
|
||||||
//* read window properties
|
|
||||||
void readWindow( WId window );
|
|
||||||
|
|
||||||
//* find window under cursor
|
|
||||||
WId findWindow();
|
|
||||||
|
|
||||||
//* execute
|
|
||||||
void executeDialog();
|
|
||||||
|
|
||||||
//* ui
|
|
||||||
Ui::BreezeDetectWidget m_ui;
|
|
||||||
|
|
||||||
//* invisible dialog used to grab mouse
|
|
||||||
QDialog* m_grabber = nullptr;
|
|
||||||
|
|
||||||
//* current window information
|
|
||||||
QScopedPointer<KWindowInfo> m_info;
|
|
||||||
|
|
||||||
//* wm state atom
|
|
||||||
quint32 m_wmStateAtom = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,168 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// breezeexceptiondialog.cpp
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "breezeexceptiondialog.h"
|
|
||||||
#include "breezedetectwidget.h"
|
|
||||||
#include "config-breeze.h"
|
|
||||||
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
#include <QX11Info>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//___________________________________________
|
|
||||||
ExceptionDialog::ExceptionDialog( QWidget* parent ):
|
|
||||||
QDialog( parent )
|
|
||||||
{
|
|
||||||
|
|
||||||
m_ui.setupUi( this );
|
|
||||||
|
|
||||||
connect( m_ui.buttonBox->button( QDialogButtonBox::Cancel ), &QAbstractButton::clicked, this, &QWidget::close );
|
|
||||||
|
|
||||||
// store checkboxes from ui into list
|
|
||||||
m_checkboxes.insert( BorderSize, m_ui.borderSizeCheckBox );
|
|
||||||
|
|
||||||
// detect window properties
|
|
||||||
connect( m_ui.detectDialogButton, &QAbstractButton::clicked, this, &ExceptionDialog::selectWindowProperties );
|
|
||||||
|
|
||||||
// connections
|
|
||||||
connect( m_ui.exceptionType, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) );
|
|
||||||
connect( m_ui.exceptionEditor, &QLineEdit::textChanged, this, &ExceptionDialog::updateChanged );
|
|
||||||
connect( m_ui.borderSizeComboBox, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) );
|
|
||||||
|
|
||||||
for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter )
|
|
||||||
{ connect( iter.value(), &QAbstractButton::clicked, this, &ExceptionDialog::updateChanged ); }
|
|
||||||
|
|
||||||
connect( m_ui.hideTitleBar, &QAbstractButton::clicked, this, &ExceptionDialog::updateChanged );
|
|
||||||
|
|
||||||
// hide detection dialog on non X11 platforms
|
|
||||||
#if BREEZE_HAVE_X11
|
|
||||||
if( !QX11Info::isPlatformX11() ) m_ui.detectDialogButton->hide();
|
|
||||||
#else
|
|
||||||
m_ui.detectDialogButton->hide();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//___________________________________________
|
|
||||||
void ExceptionDialog::setException( InternalSettingsPtr exception )
|
|
||||||
{
|
|
||||||
|
|
||||||
// store exception internally
|
|
||||||
m_exception = exception;
|
|
||||||
|
|
||||||
// type
|
|
||||||
m_ui.exceptionType->setCurrentIndex(m_exception->exceptionType() );
|
|
||||||
m_ui.exceptionEditor->setText( m_exception->exceptionPattern() );
|
|
||||||
m_ui.borderSizeComboBox->setCurrentIndex( m_exception->borderSize() );
|
|
||||||
m_ui.hideTitleBar->setChecked( m_exception->hideTitleBar() );
|
|
||||||
|
|
||||||
// mask
|
|
||||||
for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter )
|
|
||||||
{ iter.value()->setChecked( m_exception->mask() & iter.key() ); }
|
|
||||||
|
|
||||||
setChanged( false );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//___________________________________________
|
|
||||||
void ExceptionDialog::save()
|
|
||||||
{
|
|
||||||
m_exception->setExceptionType( m_ui.exceptionType->currentIndex() );
|
|
||||||
m_exception->setExceptionPattern( m_ui.exceptionEditor->text() );
|
|
||||||
m_exception->setBorderSize( m_ui.borderSizeComboBox->currentIndex() );
|
|
||||||
m_exception->setHideTitleBar( m_ui.hideTitleBar->isChecked() );
|
|
||||||
|
|
||||||
// mask
|
|
||||||
unsigned int mask = None;
|
|
||||||
for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter )
|
|
||||||
{ if( iter.value()->isChecked() ) mask |= iter.key(); }
|
|
||||||
|
|
||||||
m_exception->setMask( mask );
|
|
||||||
|
|
||||||
setChanged( false );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//___________________________________________
|
|
||||||
void ExceptionDialog::updateChanged()
|
|
||||||
{
|
|
||||||
bool modified( false );
|
|
||||||
if( m_exception->exceptionType() != m_ui.exceptionType->currentIndex() ) modified = true;
|
|
||||||
else if( m_exception->exceptionPattern() != m_ui.exceptionEditor->text() ) modified = true;
|
|
||||||
else if( m_exception->borderSize() != m_ui.borderSizeComboBox->currentIndex() ) modified = true;
|
|
||||||
else if( m_exception->hideTitleBar() != m_ui.hideTitleBar->isChecked() ) modified = true;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// check mask
|
|
||||||
for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter )
|
|
||||||
{
|
|
||||||
if( iter.value()->isChecked() != (bool)( m_exception->mask() & iter.key() ) )
|
|
||||||
{
|
|
||||||
modified = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setChanged( modified );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//___________________________________________
|
|
||||||
void ExceptionDialog::selectWindowProperties()
|
|
||||||
{
|
|
||||||
|
|
||||||
// create widget
|
|
||||||
if( !m_detectDialog )
|
|
||||||
{
|
|
||||||
m_detectDialog = new DetectDialog( this );
|
|
||||||
connect( m_detectDialog, &DetectDialog::detectionDone, this, &ExceptionDialog::readWindowProperties );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_detectDialog->detect(0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//___________________________________________
|
|
||||||
void ExceptionDialog::readWindowProperties( bool valid )
|
|
||||||
{
|
|
||||||
Q_CHECK_PTR( m_detectDialog );
|
|
||||||
if( valid )
|
|
||||||
{
|
|
||||||
|
|
||||||
// type
|
|
||||||
m_ui.exceptionType->setCurrentIndex( m_detectDialog->exceptionType() );
|
|
||||||
|
|
||||||
// window info
|
|
||||||
const KWindowInfo& info( m_detectDialog->windowInfo() );
|
|
||||||
|
|
||||||
switch( m_detectDialog->exceptionType() )
|
|
||||||
{
|
|
||||||
|
|
||||||
default:
|
|
||||||
case InternalSettings::ExceptionWindowClassName:
|
|
||||||
m_ui.exceptionEditor->setText( QString::fromUtf8( info.windowClassClass() ) );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case InternalSettings::ExceptionWindowTitle:
|
|
||||||
m_ui.exceptionEditor->setText( info.name() );
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
delete m_detectDialog;
|
|
||||||
m_detectDialog = nullptr;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,98 +0,0 @@
|
|||||||
#ifndef breezeexceptiondialog_h
|
|
||||||
#define breezeexceptiondialog_h
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// breezeexceptiondialog.h
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "ui_breezeexceptiondialog.h"
|
|
||||||
#include "breeze.h"
|
|
||||||
|
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QMap>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
class DetectDialog;
|
|
||||||
|
|
||||||
//* breeze exceptions list
|
|
||||||
class ExceptionDialog: public QDialog
|
|
||||||
{
|
|
||||||
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//* constructor
|
|
||||||
explicit ExceptionDialog( QWidget* parent );
|
|
||||||
|
|
||||||
//* destructor
|
|
||||||
virtual ~ExceptionDialog()
|
|
||||||
{}
|
|
||||||
|
|
||||||
//* set exception
|
|
||||||
void setException( InternalSettingsPtr );
|
|
||||||
|
|
||||||
//* save exception
|
|
||||||
void save();
|
|
||||||
|
|
||||||
//* true if changed
|
|
||||||
virtual bool isChanged() const
|
|
||||||
{ return m_changed; }
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
|
|
||||||
//* emitted when changed
|
|
||||||
void changed( bool );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//* set changed state
|
|
||||||
virtual void setChanged( bool value )
|
|
||||||
{
|
|
||||||
m_changed = value;
|
|
||||||
emit changed( value );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
|
|
||||||
//* check whether configuration is changed and emit appropriate signal if yes
|
|
||||||
virtual void updateChanged();
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
|
|
||||||
//* select window properties from grabbed pointers
|
|
||||||
void selectWindowProperties();
|
|
||||||
|
|
||||||
//* read properties of selected window
|
|
||||||
void readWindowProperties( bool );
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//* map mask and checkbox
|
|
||||||
using CheckBoxMap=QMap< ExceptionMask, QCheckBox*>;
|
|
||||||
|
|
||||||
Ui::BreezeExceptionDialog m_ui;
|
|
||||||
|
|
||||||
//* map mask and checkbox
|
|
||||||
CheckBoxMap m_checkboxes;
|
|
||||||
|
|
||||||
//* internal exception
|
|
||||||
InternalSettingsPtr m_exception;
|
|
||||||
|
|
||||||
//* detection dialog
|
|
||||||
DetectDialog* m_detectDialog = nullptr;
|
|
||||||
|
|
||||||
//* changed state
|
|
||||||
bool m_changed = false;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,329 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// breezeexceptionlistwidget.cpp
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "breezeexceptionlistwidget.h"
|
|
||||||
#include "breezeexceptiondialog.h"
|
|
||||||
|
|
||||||
#include <KLocalizedString>
|
|
||||||
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QPointer>
|
|
||||||
#include <QIcon>
|
|
||||||
|
|
||||||
//__________________________________________________________
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//__________________________________________________________
|
|
||||||
ExceptionListWidget::ExceptionListWidget( QWidget* parent ):
|
|
||||||
QWidget( parent )
|
|
||||||
{
|
|
||||||
|
|
||||||
// ui
|
|
||||||
m_ui.setupUi( this );
|
|
||||||
|
|
||||||
// list
|
|
||||||
m_ui.exceptionListView->setAllColumnsShowFocus( true );
|
|
||||||
m_ui.exceptionListView->setRootIsDecorated( false );
|
|
||||||
m_ui.exceptionListView->setSortingEnabled( false );
|
|
||||||
m_ui.exceptionListView->setModel( &model() );
|
|
||||||
m_ui.exceptionListView->sortByColumn( ExceptionModel::ColumnType, Qt::AscendingOrder );
|
|
||||||
m_ui.exceptionListView->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Ignored ) );
|
|
||||||
|
|
||||||
m_ui.moveUpButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-up" ) ) );
|
|
||||||
m_ui.moveDownButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-down" ) ) );
|
|
||||||
m_ui.addButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-add" ) ) );
|
|
||||||
m_ui.removeButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-remove" ) ) );
|
|
||||||
m_ui.editButton->setIcon( QIcon::fromTheme( QStringLiteral( "edit-rename" ) ) );
|
|
||||||
|
|
||||||
connect( m_ui.addButton, &QAbstractButton::clicked, this, &ExceptionListWidget::add );
|
|
||||||
connect( m_ui.editButton, &QAbstractButton::clicked, this, &ExceptionListWidget::edit );
|
|
||||||
connect( m_ui.removeButton, &QAbstractButton::clicked, this, &ExceptionListWidget::remove );
|
|
||||||
connect( m_ui.moveUpButton, &QAbstractButton::clicked, this, &ExceptionListWidget::up );
|
|
||||||
connect( m_ui.moveDownButton, &QAbstractButton::clicked, this, &ExceptionListWidget::down );
|
|
||||||
|
|
||||||
connect( m_ui.exceptionListView, &QAbstractItemView::activated, this, &ExceptionListWidget::edit );
|
|
||||||
connect( m_ui.exceptionListView, &QAbstractItemView::clicked, this, &ExceptionListWidget::toggle );
|
|
||||||
connect( m_ui.exceptionListView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ExceptionListWidget::updateButtons );
|
|
||||||
|
|
||||||
updateButtons();
|
|
||||||
resizeColumns();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________
|
|
||||||
void ExceptionListWidget::setExceptions( const InternalSettingsList& exceptions )
|
|
||||||
{
|
|
||||||
model().set( exceptions );
|
|
||||||
resizeColumns();
|
|
||||||
setChanged( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________
|
|
||||||
InternalSettingsList ExceptionListWidget::exceptions()
|
|
||||||
{
|
|
||||||
return model().get();
|
|
||||||
setChanged( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________
|
|
||||||
void ExceptionListWidget::updateButtons()
|
|
||||||
{
|
|
||||||
|
|
||||||
bool hasSelection( !m_ui.exceptionListView->selectionModel()->selectedRows().empty() );
|
|
||||||
m_ui.removeButton->setEnabled( hasSelection );
|
|
||||||
m_ui.editButton->setEnabled( hasSelection );
|
|
||||||
|
|
||||||
m_ui.moveUpButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( 0, QModelIndex() ) );
|
|
||||||
m_ui.moveDownButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( model().rowCount()-1, QModelIndex() ) );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//_______________________________________________________
|
|
||||||
void ExceptionListWidget::add()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
QPointer<ExceptionDialog> dialog = new ExceptionDialog( this );
|
|
||||||
dialog->setWindowTitle( i18n( "New Exception - Breeze Settings" ) );
|
|
||||||
InternalSettingsPtr exception( new InternalSettings() );
|
|
||||||
|
|
||||||
exception->load();
|
|
||||||
|
|
||||||
dialog->setException( exception );
|
|
||||||
|
|
||||||
// run dialog and check existence
|
|
||||||
if( !dialog->exec() )
|
|
||||||
{
|
|
||||||
delete dialog;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dialog->save();
|
|
||||||
delete dialog;
|
|
||||||
|
|
||||||
// check exceptions
|
|
||||||
if( !checkException( exception ) ) return;
|
|
||||||
|
|
||||||
// create new item
|
|
||||||
model().add( exception );
|
|
||||||
setChanged( true );
|
|
||||||
|
|
||||||
// make sure item is selected
|
|
||||||
QModelIndex index( model().index( exception ) );
|
|
||||||
if( index != m_ui.exceptionListView->selectionModel()->currentIndex() )
|
|
||||||
{
|
|
||||||
m_ui.exceptionListView->selectionModel()->select( index, QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows );
|
|
||||||
m_ui.exceptionListView->selectionModel()->setCurrentIndex( index, QItemSelectionModel::Current|QItemSelectionModel::Rows );
|
|
||||||
}
|
|
||||||
|
|
||||||
resizeColumns();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________________
|
|
||||||
void ExceptionListWidget::edit()
|
|
||||||
{
|
|
||||||
|
|
||||||
// retrieve selection
|
|
||||||
QModelIndex current( m_ui.exceptionListView->selectionModel()->currentIndex() );
|
|
||||||
if( ! model().contains( current ) ) return;
|
|
||||||
|
|
||||||
InternalSettingsPtr exception( model().get( current ) );
|
|
||||||
|
|
||||||
// create dialog
|
|
||||||
QPointer<ExceptionDialog> dialog( new ExceptionDialog( this ) );
|
|
||||||
dialog->setWindowTitle( i18n( "Edit Exception - Breeze Settings" ) );
|
|
||||||
dialog->setException( exception );
|
|
||||||
|
|
||||||
// map dialog
|
|
||||||
if( !dialog->exec() )
|
|
||||||
{
|
|
||||||
delete dialog;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check modifications
|
|
||||||
if( !dialog->isChanged() ) return;
|
|
||||||
|
|
||||||
// retrieve exception
|
|
||||||
dialog->save();
|
|
||||||
delete dialog;
|
|
||||||
|
|
||||||
// check new exception validity
|
|
||||||
checkException( exception );
|
|
||||||
resizeColumns();
|
|
||||||
|
|
||||||
setChanged( true );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________________
|
|
||||||
void ExceptionListWidget::remove()
|
|
||||||
{
|
|
||||||
|
|
||||||
// confirmation dialog
|
|
||||||
{
|
|
||||||
QMessageBox messageBox( QMessageBox::Question, i18n("Question - Breeze Settings" ), i18n("Remove selected exception?"), QMessageBox::Yes | QMessageBox::Cancel );
|
|
||||||
messageBox.button( QMessageBox::Yes )->setText( i18n("Remove") );
|
|
||||||
messageBox.setDefaultButton( QMessageBox::Cancel );
|
|
||||||
if( messageBox.exec() == QMessageBox::Cancel ) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove
|
|
||||||
model().remove( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) );
|
|
||||||
resizeColumns();
|
|
||||||
updateButtons();
|
|
||||||
|
|
||||||
setChanged( true );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________________
|
|
||||||
void ExceptionListWidget::toggle( const QModelIndex& index )
|
|
||||||
{
|
|
||||||
|
|
||||||
if( !model().contains( index ) ) return;
|
|
||||||
if( index.column() != ExceptionModel::ColumnEnabled ) return;
|
|
||||||
|
|
||||||
// get matching exception
|
|
||||||
InternalSettingsPtr exception( model().get( index ) );
|
|
||||||
exception->setEnabled( !exception->enabled() );
|
|
||||||
setChanged( true );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________________
|
|
||||||
void ExceptionListWidget::up()
|
|
||||||
{
|
|
||||||
|
|
||||||
InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) );
|
|
||||||
if( selection.empty() ) { return; }
|
|
||||||
|
|
||||||
// retrieve selected indexes in list and store in model
|
|
||||||
QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedRows() );
|
|
||||||
InternalSettingsList selectedExceptions( model().get( selectedIndices ) );
|
|
||||||
|
|
||||||
InternalSettingsList currentException( model().get() );
|
|
||||||
InternalSettingsList newExceptions;
|
|
||||||
|
|
||||||
for( InternalSettingsList::const_iterator iter = currentException.constBegin(); iter != currentException.constEnd(); ++iter )
|
|
||||||
{
|
|
||||||
|
|
||||||
// check if new list is not empty, current index is selected and last index is not.
|
|
||||||
// if yes, move.
|
|
||||||
if(
|
|
||||||
!( newExceptions.empty() ||
|
|
||||||
selectedIndices.indexOf( model().index( *iter ) ) == -1 ||
|
|
||||||
selectedIndices.indexOf( model().index( newExceptions.back() ) ) != -1
|
|
||||||
) )
|
|
||||||
{
|
|
||||||
InternalSettingsPtr last( newExceptions.back() );
|
|
||||||
newExceptions.removeLast();
|
|
||||||
newExceptions.append( *iter );
|
|
||||||
newExceptions.append( last );
|
|
||||||
} else newExceptions.append( *iter );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
model().set( newExceptions );
|
|
||||||
|
|
||||||
// restore selection
|
|
||||||
m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows );
|
|
||||||
for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter )
|
|
||||||
{ m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); }
|
|
||||||
|
|
||||||
setChanged( true );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________________
|
|
||||||
void ExceptionListWidget::down()
|
|
||||||
{
|
|
||||||
|
|
||||||
InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) );
|
|
||||||
if( selection.empty() )
|
|
||||||
{ return; }
|
|
||||||
|
|
||||||
// retrieve selected indexes in list and store in model
|
|
||||||
QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedIndexes() );
|
|
||||||
InternalSettingsList selectedExceptions( model().get( selectedIndices ) );
|
|
||||||
|
|
||||||
InternalSettingsList currentExceptions( model().get() );
|
|
||||||
InternalSettingsList newExceptions;
|
|
||||||
|
|
||||||
InternalSettingsListIterator iter( currentExceptions );
|
|
||||||
iter.toBack();
|
|
||||||
while( iter.hasPrevious() )
|
|
||||||
{
|
|
||||||
|
|
||||||
InternalSettingsPtr current( iter.previous() );
|
|
||||||
|
|
||||||
// check if new list is not empty, current index is selected and last index is not.
|
|
||||||
// if yes, move.
|
|
||||||
if(
|
|
||||||
!( newExceptions.empty() ||
|
|
||||||
selectedIndices.indexOf( model().index( current ) ) == -1 ||
|
|
||||||
selectedIndices.indexOf( model().index( newExceptions.front() ) ) != -1
|
|
||||||
) )
|
|
||||||
{
|
|
||||||
|
|
||||||
InternalSettingsPtr first( newExceptions.front() );
|
|
||||||
newExceptions.removeFirst();
|
|
||||||
newExceptions.prepend( current );
|
|
||||||
newExceptions.prepend( first );
|
|
||||||
|
|
||||||
} else newExceptions.prepend( current );
|
|
||||||
}
|
|
||||||
|
|
||||||
model().set( newExceptions );
|
|
||||||
|
|
||||||
// restore selection
|
|
||||||
m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows );
|
|
||||||
for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter )
|
|
||||||
{ m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); }
|
|
||||||
|
|
||||||
setChanged( true );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________________
|
|
||||||
void ExceptionListWidget::resizeColumns() const
|
|
||||||
{
|
|
||||||
m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnEnabled );
|
|
||||||
m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnType );
|
|
||||||
m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnRegExp );
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________________
|
|
||||||
bool ExceptionListWidget::checkException( InternalSettingsPtr exception )
|
|
||||||
{
|
|
||||||
|
|
||||||
while( exception->exceptionPattern().isEmpty() || !QRegExp( exception->exceptionPattern() ).isValid() )
|
|
||||||
{
|
|
||||||
|
|
||||||
QMessageBox::warning( this, i18n( "Warning - Breeze Settings" ), i18n("Regular Expression syntax is incorrect") );
|
|
||||||
QPointer<ExceptionDialog> dialog( new ExceptionDialog( this ) );
|
|
||||||
dialog->setException( exception );
|
|
||||||
if( dialog->exec() == QDialog::Rejected )
|
|
||||||
{
|
|
||||||
delete dialog;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dialog->save();
|
|
||||||
delete dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,108 +0,0 @@
|
|||||||
#ifndef breezeexceptionlistwidget_h
|
|
||||||
#define breezeexceptionlistwidget_h
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// breezeexceptionlistwidget.h
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "ui_breezeexceptionlistwidget.h"
|
|
||||||
#include "breezeexceptionmodel.h"
|
|
||||||
|
|
||||||
//* QDialog used to commit selected files
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
class ExceptionListWidget: public QWidget
|
|
||||||
{
|
|
||||||
|
|
||||||
//* Qt meta object
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//* constructor
|
|
||||||
explicit ExceptionListWidget( QWidget* = nullptr );
|
|
||||||
|
|
||||||
//* set exceptions
|
|
||||||
void setExceptions( const InternalSettingsList& );
|
|
||||||
|
|
||||||
//* get exceptions
|
|
||||||
InternalSettingsList exceptions();
|
|
||||||
|
|
||||||
//* true if changed
|
|
||||||
virtual bool isChanged() const
|
|
||||||
{ return m_changed; }
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
|
|
||||||
//* emitted when changed
|
|
||||||
void changed( bool );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//* model
|
|
||||||
const ExceptionModel& model() const
|
|
||||||
{ return m_model; }
|
|
||||||
|
|
||||||
//* model
|
|
||||||
ExceptionModel& model()
|
|
||||||
{ return m_model; }
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
|
|
||||||
//* update button states
|
|
||||||
virtual void updateButtons();
|
|
||||||
|
|
||||||
//* add
|
|
||||||
virtual void add();
|
|
||||||
|
|
||||||
//* edit
|
|
||||||
virtual void edit();
|
|
||||||
|
|
||||||
//* remove
|
|
||||||
virtual void remove();
|
|
||||||
|
|
||||||
//* toggle
|
|
||||||
virtual void toggle( const QModelIndex& );
|
|
||||||
|
|
||||||
//* move up
|
|
||||||
virtual void up();
|
|
||||||
|
|
||||||
//* move down
|
|
||||||
virtual void down();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//* resize columns
|
|
||||||
void resizeColumns() const;
|
|
||||||
|
|
||||||
//* check exception
|
|
||||||
bool checkException( InternalSettingsPtr );
|
|
||||||
|
|
||||||
//* set changed state
|
|
||||||
virtual void setChanged( bool value )
|
|
||||||
{
|
|
||||||
m_changed = value;
|
|
||||||
emit changed( value );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//* model
|
|
||||||
ExceptionModel m_model;
|
|
||||||
|
|
||||||
//* ui
|
|
||||||
Ui_BreezeExceptionListWidget m_ui;
|
|
||||||
|
|
||||||
//* changed state
|
|
||||||
bool m_changed = false;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// breezeexceptionmodel.cpp
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "breezeexceptionmodel.h"
|
|
||||||
|
|
||||||
#include <KLocalizedString>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//_______________________________________________
|
|
||||||
const QString ExceptionModel::m_columnTitles[ ExceptionModel::nColumns ] =
|
|
||||||
{
|
|
||||||
QStringLiteral( "" ),
|
|
||||||
i18n("Exception Type"),
|
|
||||||
i18n("Regular Expression")
|
|
||||||
};
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
QVariant ExceptionModel::data( const QModelIndex& index, int role ) const
|
|
||||||
{
|
|
||||||
|
|
||||||
// check index, role and column
|
|
||||||
if( !index.isValid() ) return QVariant();
|
|
||||||
|
|
||||||
// retrieve associated file info
|
|
||||||
const InternalSettingsPtr& configuration( get(index) );
|
|
||||||
|
|
||||||
// return text associated to file and column
|
|
||||||
if( role == Qt::DisplayRole )
|
|
||||||
{
|
|
||||||
|
|
||||||
switch( index.column() )
|
|
||||||
{
|
|
||||||
case ColumnType:
|
|
||||||
{
|
|
||||||
switch( configuration->exceptionType() )
|
|
||||||
{
|
|
||||||
|
|
||||||
case InternalSettings::ExceptionWindowTitle:
|
|
||||||
return i18n( "Window Title" );
|
|
||||||
|
|
||||||
default:
|
|
||||||
case InternalSettings::ExceptionWindowClassName:
|
|
||||||
return i18n( "Window Class Name" );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
case ColumnRegExp: return configuration->exceptionPattern();
|
|
||||||
default: return QVariant();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if( role == Qt::CheckStateRole && index.column() == ColumnEnabled ) {
|
|
||||||
|
|
||||||
return configuration->enabled() ? Qt::Checked : Qt::Unchecked;
|
|
||||||
|
|
||||||
} else if( role == Qt::ToolTipRole && index.column() == ColumnEnabled ) {
|
|
||||||
|
|
||||||
return i18n("Enable/disable this exception");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________________
|
|
||||||
QVariant ExceptionModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
||||||
{
|
|
||||||
|
|
||||||
if(
|
|
||||||
orientation == Qt::Horizontal &&
|
|
||||||
role == Qt::DisplayRole &&
|
|
||||||
section >= 0 &&
|
|
||||||
section < nColumns )
|
|
||||||
{ return m_columnTitles[section]; }
|
|
||||||
|
|
||||||
// return empty
|
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
#ifndef breezeexceptionmodel_h
|
|
||||||
#define breezeexceptionmodel_h
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// breezeexceptionmodel.h
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "breezelistmodel.h"
|
|
||||||
#include "breezesettings.h"
|
|
||||||
#include "breeze.h"
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//* qlistview for object counters
|
|
||||||
class ExceptionModel: public ListModel<InternalSettingsPtr>
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//* number of columns
|
|
||||||
enum { nColumns = 3 };
|
|
||||||
|
|
||||||
//* column type enumeration
|
|
||||||
enum ColumnType {
|
|
||||||
ColumnEnabled,
|
|
||||||
ColumnType,
|
|
||||||
ColumnRegExp
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//*@name methods reimplemented from base class
|
|
||||||
//@{
|
|
||||||
|
|
||||||
//* return data for a given index
|
|
||||||
QVariant data(const QModelIndex &index, int role) const override;
|
|
||||||
|
|
||||||
//* header data
|
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
|
||||||
|
|
||||||
//* number of columns for a given index
|
|
||||||
int columnCount(const QModelIndex& ) const override
|
|
||||||
{ return nColumns; }
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//* sort
|
|
||||||
void privateSort( int, Qt::SortOrder ) override
|
|
||||||
{}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//* column titles
|
|
||||||
static const QString m_columnTitles[ nColumns ];
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// itemmodel.cpp
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009-2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "breezeitemmodel.h"
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//_______________________________________________________________
|
|
||||||
ItemModel::ItemModel( QObject* parent ):
|
|
||||||
QAbstractItemModel( parent )
|
|
||||||
{}
|
|
||||||
|
|
||||||
//____________________________________________________________
|
|
||||||
void ItemModel::sort( int column, Qt::SortOrder order )
|
|
||||||
{
|
|
||||||
|
|
||||||
// store column and order
|
|
||||||
m_sortColumn = column;
|
|
||||||
m_sortOrder = order;
|
|
||||||
|
|
||||||
// emit signals and call private methods
|
|
||||||
emit layoutAboutToBeChanged();
|
|
||||||
privateSort( column, order );
|
|
||||||
emit layoutChanged();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//____________________________________________________________
|
|
||||||
QModelIndexList ItemModel::indexes( int column, const QModelIndex& parent ) const
|
|
||||||
{
|
|
||||||
QModelIndexList out;
|
|
||||||
int rows( rowCount( parent ) );
|
|
||||||
for( int row = 0; row < rows; row++ )
|
|
||||||
{
|
|
||||||
QModelIndex index( this->index( row, column, parent ) );
|
|
||||||
if( !index.isValid() ) continue;
|
|
||||||
out.append( index );
|
|
||||||
out += indexes( column, index );
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
#ifndef ItemModel_h
|
|
||||||
#define ItemModel_h
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// itemmodel.h
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009-2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
//* Job model. Stores job information for display in lists
|
|
||||||
class ItemModel : public QAbstractItemModel
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//* constructor
|
|
||||||
explicit ItemModel(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
//* destructor
|
|
||||||
virtual ~ItemModel()
|
|
||||||
{}
|
|
||||||
|
|
||||||
//* return all indexes in model starting from parent [recursive]
|
|
||||||
QModelIndexList indexes( int column = 0, const QModelIndex& parent = QModelIndex() ) const;
|
|
||||||
|
|
||||||
//*@name sorting
|
|
||||||
//@{
|
|
||||||
|
|
||||||
//* sort
|
|
||||||
virtual void sort()
|
|
||||||
{ sort( sortColumn(), sortOrder() ); }
|
|
||||||
|
|
||||||
//* sort
|
|
||||||
void sort( int column, Qt::SortOrder order = Qt::AscendingOrder ) override;
|
|
||||||
|
|
||||||
//* current sorting column
|
|
||||||
const int& sortColumn() const
|
|
||||||
{ return m_sortColumn; }
|
|
||||||
|
|
||||||
//* current sort order
|
|
||||||
const Qt::SortOrder& sortOrder() const
|
|
||||||
{ return m_sortOrder; }
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//* this sort columns without calling the layout changed callbacks
|
|
||||||
void privateSort()
|
|
||||||
{ privateSort( m_sortColumn, m_sortOrder ); }
|
|
||||||
|
|
||||||
//* private sort, with no signals emitted
|
|
||||||
virtual void privateSort( int column, Qt::SortOrder order ) = 0;
|
|
||||||
|
|
||||||
//* used to sort items in list
|
|
||||||
class SortFTor
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//* constructor
|
|
||||||
explicit SortFTor( const int& type, Qt::SortOrder order = Qt::AscendingOrder ):
|
|
||||||
_type( type ),
|
|
||||||
_order( order )
|
|
||||||
{}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//* column
|
|
||||||
int _type;
|
|
||||||
|
|
||||||
//* order
|
|
||||||
Qt::SortOrder _order;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//* sorting column
|
|
||||||
int m_sortColumn = 0;
|
|
||||||
|
|
||||||
//* sorting order
|
|
||||||
Qt::SortOrder m_sortOrder = Qt::AscendingOrder;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,349 +0,0 @@
|
|||||||
#ifndef ListModel_h
|
|
||||||
#define ListModel_h
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// listmodel.h
|
|
||||||
// -------------------
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "breezeitemmodel.h"
|
|
||||||
|
|
||||||
#include <QSet>
|
|
||||||
#include <QList>
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
//! Job model. Stores job information for display in lists
|
|
||||||
template<class T> class ListModel : public ItemModel
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! value type
|
|
||||||
typedef T ValueType;
|
|
||||||
|
|
||||||
//! reference
|
|
||||||
typedef T& Reference;
|
|
||||||
|
|
||||||
//! pointer
|
|
||||||
typedef T* Pointer;
|
|
||||||
|
|
||||||
//! value list and iterators
|
|
||||||
typedef QList<ValueType> List;
|
|
||||||
typedef QListIterator<ValueType> ListIterator;
|
|
||||||
typedef QMutableListIterator<ValueType> MutableListIterator;
|
|
||||||
|
|
||||||
//! list of vector
|
|
||||||
// typedef QSet<ValueType> Set;
|
|
||||||
|
|
||||||
//! constructor
|
|
||||||
ListModel(QObject *parent = nullptr):
|
|
||||||
ItemModel( parent )
|
|
||||||
{}
|
|
||||||
|
|
||||||
//! destructor
|
|
||||||
virtual ~ListModel()
|
|
||||||
{}
|
|
||||||
|
|
||||||
//!@name methods reimplemented from base class
|
|
||||||
//@{
|
|
||||||
|
|
||||||
//! flags
|
|
||||||
Qt::ItemFlags flags(const QModelIndex &index) const override
|
|
||||||
{
|
|
||||||
if (!index.isValid()) return Qt::NoItemFlags;
|
|
||||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! unique index for given row, column and parent index
|
|
||||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
|
|
||||||
{
|
|
||||||
|
|
||||||
// check if index is valid
|
|
||||||
if( !hasIndex( row, column, parent ) ) return QModelIndex();
|
|
||||||
|
|
||||||
// return invalid index if parent is valid
|
|
||||||
if( parent.isValid() ) return QModelIndex();
|
|
||||||
|
|
||||||
// check against _values
|
|
||||||
return ( row < (int) _values.size() ) ? createIndex( row, column ):QModelIndex();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//! index of parent
|
|
||||||
QModelIndex parent(const QModelIndex &) const override
|
|
||||||
{ return QModelIndex(); }
|
|
||||||
|
|
||||||
//! number of rows below given index
|
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
|
||||||
{ return parent.isValid() ? 0:_values.size(); }
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//!@name selection
|
|
||||||
//@{
|
|
||||||
|
|
||||||
//! clear internal list selected items
|
|
||||||
virtual void clearSelectedIndexes()
|
|
||||||
{ _selection.clear(); }
|
|
||||||
|
|
||||||
//! store index internal selection state
|
|
||||||
virtual void setIndexSelected( const QModelIndex& index, bool value )
|
|
||||||
{
|
|
||||||
if( value ) _selection.push_back( get(index) );
|
|
||||||
else _selection.erase( std::remove( _selection.begin(), _selection.end(), get(index) ), _selection.end() );
|
|
||||||
}
|
|
||||||
|
|
||||||
//! get list of internal selected items
|
|
||||||
virtual QModelIndexList selectedIndexes() const
|
|
||||||
{
|
|
||||||
|
|
||||||
QModelIndexList out;
|
|
||||||
for( typename List::const_iterator iter = _selection.begin(); iter != _selection.end(); iter++ )
|
|
||||||
{
|
|
||||||
QModelIndex index( ListModel::index( *iter ) );
|
|
||||||
if( index.isValid() ) out.push_back( index );
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//!@name interface
|
|
||||||
//@{
|
|
||||||
|
|
||||||
//! add value
|
|
||||||
virtual void add( const ValueType& value )
|
|
||||||
{
|
|
||||||
|
|
||||||
emit layoutAboutToBeChanged();
|
|
||||||
_add( value );
|
|
||||||
privateSort();
|
|
||||||
emit layoutChanged();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//! add values
|
|
||||||
virtual void add( const List& values )
|
|
||||||
{
|
|
||||||
|
|
||||||
// check if not empty
|
|
||||||
// this avoids sending useless signals
|
|
||||||
if( values.empty() ) return;
|
|
||||||
|
|
||||||
emit layoutAboutToBeChanged();
|
|
||||||
|
|
||||||
for( typename List::const_iterator iter = values.begin(); iter != values.end(); iter++ )
|
|
||||||
{ _add( *iter ); }
|
|
||||||
|
|
||||||
privateSort();
|
|
||||||
emit layoutChanged();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! insert values
|
|
||||||
virtual void insert( const QModelIndex& index, const ValueType& value )
|
|
||||||
{
|
|
||||||
emit layoutAboutToBeChanged();
|
|
||||||
_insert( index, value );
|
|
||||||
emit layoutChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! insert values
|
|
||||||
virtual void insert( const QModelIndex& index, const List& values )
|
|
||||||
{
|
|
||||||
emit layoutAboutToBeChanged();
|
|
||||||
|
|
||||||
// need to loop in reverse order so that the "values" ordering is preserved
|
|
||||||
ListIterator iter( values );
|
|
||||||
iter.toBack();
|
|
||||||
while( iter.hasPrevious() )
|
|
||||||
{ _insert( index, iter.previous() ); }
|
|
||||||
|
|
||||||
emit layoutChanged();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//! insert values
|
|
||||||
virtual void replace( const QModelIndex& index, const ValueType& value )
|
|
||||||
{
|
|
||||||
if( !index.isValid() ) add( value );
|
|
||||||
else {
|
|
||||||
emit layoutAboutToBeChanged();
|
|
||||||
setIndexSelected( index, false );
|
|
||||||
_values[index.row()] = value;
|
|
||||||
setIndexSelected( index, true );
|
|
||||||
emit layoutChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//! remove
|
|
||||||
virtual void remove( const ValueType& value )
|
|
||||||
{
|
|
||||||
|
|
||||||
emit layoutAboutToBeChanged();
|
|
||||||
_remove( value );
|
|
||||||
emit layoutChanged();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//! remove
|
|
||||||
virtual void remove( const List& values )
|
|
||||||
{
|
|
||||||
|
|
||||||
// check if not empty
|
|
||||||
// this avoids sending useless signals
|
|
||||||
if( values.empty() ) return;
|
|
||||||
|
|
||||||
emit layoutAboutToBeChanged();
|
|
||||||
for( typename List::const_iterator iter = values.begin(); iter != values.end(); iter++ )
|
|
||||||
{ _remove( *iter ); }
|
|
||||||
emit layoutChanged();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//! clear
|
|
||||||
virtual void clear()
|
|
||||||
{ set( List() ); }
|
|
||||||
|
|
||||||
//! update values from list
|
|
||||||
/*!
|
|
||||||
values that are not found in current are removed
|
|
||||||
new values are set to the end.
|
|
||||||
This is slower than the "set" method, but the selection is not cleared in the process
|
|
||||||
*/
|
|
||||||
virtual void update( List values )
|
|
||||||
{
|
|
||||||
|
|
||||||
emit layoutAboutToBeChanged();
|
|
||||||
|
|
||||||
// store values to be removed
|
|
||||||
List removed_values;
|
|
||||||
|
|
||||||
// update values that are common to both lists
|
|
||||||
for( typename List::iterator iter = _values.begin(); iter != _values.end(); iter++ )
|
|
||||||
{
|
|
||||||
|
|
||||||
// see if iterator is in list
|
|
||||||
typename List::iterator found_iter( std::find( values.begin(), values.end(), *iter ) );
|
|
||||||
if( found_iter == values.end() ) removed_values.push_back( *iter );
|
|
||||||
else {
|
|
||||||
*iter = *found_iter;
|
|
||||||
values.erase( found_iter );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove values that have not been found in new list
|
|
||||||
for( typename List::const_iterator iter = removed_values.constBegin(); iter != removed_values.constEnd(); iter++ )
|
|
||||||
{ _remove( *iter ); }
|
|
||||||
|
|
||||||
// add remaining values
|
|
||||||
for( typename List::const_iterator iter = values.constBegin(); iter != values.constEnd(); iter++ )
|
|
||||||
{ _add( *iter ); }
|
|
||||||
|
|
||||||
privateSort();
|
|
||||||
emit layoutChanged();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//! set all values
|
|
||||||
virtual void set( const List& values )
|
|
||||||
{
|
|
||||||
|
|
||||||
emit layoutAboutToBeChanged();
|
|
||||||
_values = values;
|
|
||||||
_selection.clear();
|
|
||||||
privateSort();
|
|
||||||
emit layoutChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! return all values
|
|
||||||
const List& get( void ) const
|
|
||||||
{ return _values; }
|
|
||||||
|
|
||||||
//! return value for given index
|
|
||||||
virtual ValueType get( const QModelIndex& index ) const
|
|
||||||
{ return (index.isValid() && index.row() < int(_values.size()) ) ? _values[index.row()]:ValueType(); }
|
|
||||||
|
|
||||||
//! return value for given index
|
|
||||||
virtual ValueType& get( const QModelIndex& index )
|
|
||||||
{
|
|
||||||
Q_ASSERT( index.isValid() && index.row() < int( _values.size() ) );
|
|
||||||
return _values[index.row()];
|
|
||||||
}
|
|
||||||
|
|
||||||
//! return all values
|
|
||||||
List get( const QModelIndexList& indexes ) const
|
|
||||||
{
|
|
||||||
List out;
|
|
||||||
for( QModelIndexList::const_iterator iter = indexes.begin(); iter != indexes.end(); iter++ )
|
|
||||||
{ if( iter->isValid() && iter->row() < int(_values.size()) ) out.push_back( get( *iter ) ); }
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! return index associated to a given value
|
|
||||||
virtual QModelIndex index( const ValueType& value, int column = 0 ) const
|
|
||||||
{
|
|
||||||
for( int row = 0; row < _values.size(); ++row )
|
|
||||||
{ if( value == _values[row] ) return index( row, column ); }
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! return true if model contains given index
|
|
||||||
virtual bool contains( const QModelIndex& index ) const
|
|
||||||
{ return index.isValid() && index.row() < _values.size(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//! return all values
|
|
||||||
List& _get( void )
|
|
||||||
{ return _values; }
|
|
||||||
|
|
||||||
//! add, without update
|
|
||||||
virtual void _add( const ValueType& value )
|
|
||||||
{
|
|
||||||
typename List::iterator iter = std::find( _values.begin(), _values.end(), value );
|
|
||||||
if( iter == _values.end() ) _values.push_back( value );
|
|
||||||
else *iter = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! add, without update
|
|
||||||
virtual void _insert( const QModelIndex& index, const ValueType& value )
|
|
||||||
{
|
|
||||||
if( !index.isValid() ) add( value );
|
|
||||||
int row = 0;
|
|
||||||
typename List::iterator iter( _values.begin() );
|
|
||||||
for( ;iter != _values.end() && row != index.row(); iter++, row++ )
|
|
||||||
{}
|
|
||||||
|
|
||||||
_values.insert( iter, value );
|
|
||||||
}
|
|
||||||
|
|
||||||
//! remove, without update
|
|
||||||
virtual void _remove( const ValueType& value )
|
|
||||||
{
|
|
||||||
_values.erase( std::remove( _values.begin(), _values.end(), value ), _values.end() );
|
|
||||||
_selection.erase( std::remove( _selection.begin(), _selection.end(), value ), _selection.end() );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//! values
|
|
||||||
List _values;
|
|
||||||
|
|
||||||
//! selection
|
|
||||||
List _selection;
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -1,341 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>BreezeConfigurationUI</class>
|
|
||||||
<widget class="QWidget" name="BreezeConfigurationUI">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>428</width>
|
|
||||||
<height>418</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="tab">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>General</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Tit&le alignment:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>titleAlignment</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>B&utton size:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>buttonSize</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QComboBox" name="buttonSize">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Tiny</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Button size:">Small</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Button size:">Medium</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Button size:">Large</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Button size:">Very Large</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QComboBox" name="titleAlignment">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Left</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Center</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Center (Full Width)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Right</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="0" colspan="3">
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0" colspan="3">
|
|
||||||
<widget class="QCheckBox" name="drawSizeGrip">
|
|
||||||
<property name="text">
|
|
||||||
<string>Add handle to resize windows with no border</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0" colspan="3">
|
|
||||||
<widget class="QCheckBox" name="drawTitleBarSeparator">
|
|
||||||
<property name="text">
|
|
||||||
<string>Draw separator under active window's titlebar</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0" colspan="3">
|
|
||||||
<widget class="QCheckBox" name="drawBorderOnMaximizedWindows">
|
|
||||||
<property name="text">
|
|
||||||
<string>Allow resizing maximized windows from window edges</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="3">
|
|
||||||
<widget class="QCheckBox" name="outlineCloseButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Draw a circle around close button</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0" colspan="3">
|
|
||||||
<widget class="QCheckBox" name="drawBackgroundGradient">
|
|
||||||
<property name="text">
|
|
||||||
<string>Draw titlebar background gradient</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="tab_4">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Shadows</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Si&ze:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>shadowSize</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QComboBox" name="shadowSize">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Button size:">None</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Button size:">Small</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Button size:">Medium</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Button size:">Large</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Button size:">Very Large</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string comment="strength of the shadow (from transparent to opaque)">S&trength:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>shadowStrength</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QSpinBox" name="shadowStrength">
|
|
||||||
<property name="suffix">
|
|
||||||
<string>%</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>100</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<spacer name="horizontalSpacer_5">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="text">
|
|
||||||
<string>Color:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="KColorButton" name="shadowColor"/>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0" colspan="3">
|
|
||||||
<spacer name="verticalSpacer_3">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="tab_3">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Window-Specific Overrides</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
|
||||||
<item>
|
|
||||||
<widget class="Breeze::ExceptionListWidget" name="exceptions" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>KColorButton</class>
|
|
||||||
<extends>QPushButton</extends>
|
|
||||||
<header>kcolorbutton.h</header>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>Breeze::ExceptionListWidget</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>config/breezeexceptionlistwidget.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<tabstops>
|
|
||||||
<tabstop>tabWidget</tabstop>
|
|
||||||
<tabstop>titleAlignment</tabstop>
|
|
||||||
<tabstop>buttonSize</tabstop>
|
|
||||||
<tabstop>outlineCloseButton</tabstop>
|
|
||||||
<tabstop>drawBorderOnMaximizedWindows</tabstop>
|
|
||||||
<tabstop>drawBackgroundGradient</tabstop>
|
|
||||||
<tabstop>drawSizeGrip</tabstop>
|
|
||||||
<tabstop>drawTitleBarSeparator</tabstop>
|
|
||||||
<tabstop>shadowSize</tabstop>
|
|
||||||
<tabstop>shadowStrength</tabstop>
|
|
||||||
<tabstop>shadowColor</tabstop>
|
|
||||||
</tabstops>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>BreezeDetectWidget</class>
|
|
||||||
<widget class="QDialog" name="BreezeDetectWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>400</width>
|
|
||||||
<height>239</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Dialog</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Information about Selected Window</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Class: </string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLabel" name="windowClass">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">TextLabel</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Title: </string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLabel" name="windowTitle">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">TextLabel</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
|
||||||
<property name="title">
|
|
||||||
<string>Window Property Selection</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="windowClassCheckBox">
|
|
||||||
<property name="text">
|
|
||||||
<string>Use window class (whole application)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="windowTitleCheckBox">
|
|
||||||
<property name="locale">
|
|
||||||
<locale language="French" country="France"/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Use window title</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>BreezeDetectWidget</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>248</x>
|
|
||||||
<y>254</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>157</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>BreezeDetectWidget</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>316</x>
|
|
||||||
<y>260</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>286</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
||||||
@ -1,231 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>BreezeExceptionDialog</class>
|
|
||||||
<widget class="QDialog" name="BreezeExceptionDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>362</width>
|
|
||||||
<height>321</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Dialog</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Window Identification</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Matching window property: </string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>exceptionType</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Regular expression &to match: </string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>exceptionEditor</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="2">
|
|
||||||
<widget class="QPushButton" name="detectDialogButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Detect Window Properties</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1" colspan="2">
|
|
||||||
<widget class="QLineEdit" name="exceptionEditor">
|
|
||||||
<property name="showClearButton" stdset="0">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1" colspan="2">
|
|
||||||
<widget class="QComboBox" name="exceptionType">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Window Class Name</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Window Title</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
|
||||||
<property name="title">
|
|
||||||
<string>Decoration Options</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QCheckBox" name="borderSizeCheckBox">
|
|
||||||
<property name="text">
|
|
||||||
<string>Border size:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="2">
|
|
||||||
<widget class="QCheckBox" name="hideTitleBar">
|
|
||||||
<property name="text">
|
|
||||||
<string>Hide window title bar</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QComboBox" name="borderSizeComboBox">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Border size:">No Border</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Border size:">No Side Borders</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Border size:">Tiny</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Border size:">Normal</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Border size:">Large</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Border size:">Very Large</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Border size:">Huge</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Border size:">Very Huge</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string comment="@item:inlistbox Border size:">Oversized</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0" colspan="2">
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>BreezeExceptionDialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>252</x>
|
|
||||||
<y>342</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>157</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>BreezeExceptionDialog</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>320</x>
|
|
||||||
<y>342</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>286</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>borderSizeCheckBox</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>borderSizeComboBox</receiver>
|
|
||||||
<slot>setEnabled(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>125</x>
|
|
||||||
<y>162</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>316</x>
|
|
||||||
<y>163</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
||||||
@ -1,114 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>BreezeExceptionListWidget</class>
|
|
||||||
<widget class="QWidget" name="BreezeExceptionListWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>473</width>
|
|
||||||
<height>182</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item row="0" column="0" rowspan="6">
|
|
||||||
<widget class="QTreeView" name="exceptionListView">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>100</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>1</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QPushButton" name="moveUpButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Move Up</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QPushButton" name="moveDownButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Move Down</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QPushButton" name="addButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Add</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QPushButton" name="removeButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Remove</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QPushButton" name="editButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Edit</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<tabstops>
|
|
||||||
<tabstop>exceptionListView</tabstop>
|
|
||||||
<tabstop>moveUpButton</tabstop>
|
|
||||||
<tabstop>moveDownButton</tabstop>
|
|
||||||
<tabstop>addButton</tabstop>
|
|
||||||
<tabstop>removeButton</tabstop>
|
|
||||||
<tabstop>editButton</tabstop>
|
|
||||||
</tabstops>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
################# dependencies #################
|
|
||||||
### Qt/KDE
|
|
||||||
find_package(Qt5 REQUIRED CONFIG COMPONENTS Widgets)
|
|
||||||
|
|
||||||
################# breezestyle target #################
|
|
||||||
set(breezecommon_LIB_SRCS
|
|
||||||
breezeboxshadowrenderer.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(kali-breezecommon5 ${breezecommon_LIB_SRCS})
|
|
||||||
|
|
||||||
generate_export_header(kali-breezecommon5
|
|
||||||
BASE_NAME breezecommon
|
|
||||||
EXPORT_FILE_NAME breezecommon_export.h)
|
|
||||||
|
|
||||||
target_link_libraries(kali-breezecommon5
|
|
||||||
PUBLIC
|
|
||||||
Qt5::Core
|
|
||||||
Qt5::Gui)
|
|
||||||
@ -1,350 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
||||||
*
|
|
||||||
* The box blur implementation is based on AlphaBoxBlur from Firefox.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
// own
|
|
||||||
#include "breezeboxshadowrenderer.h"
|
|
||||||
|
|
||||||
// Qt
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QtMath>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
static inline int calculateBlurRadius(qreal stdDev)
|
|
||||||
{
|
|
||||||
// See https://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement
|
|
||||||
const qreal gaussianScaleFactor = (3.0 * qSqrt(2.0 * M_PI) / 4.0) * 1.5;
|
|
||||||
return qMax(2, qFloor(stdDev * gaussianScaleFactor + 0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline qreal calculateBlurStdDev(int radius)
|
|
||||||
{
|
|
||||||
// See https://www.w3.org/TR/css-backgrounds-3/#shadow-blur
|
|
||||||
return radius * 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline QSize calculateBlurExtent(int radius)
|
|
||||||
{
|
|
||||||
const int blurRadius = calculateBlurRadius(calculateBlurStdDev(radius));
|
|
||||||
return QSize(blurRadius, blurRadius);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct BoxLobes
|
|
||||||
{
|
|
||||||
int left; ///< how many pixels sample to the left
|
|
||||||
int right; ///< how many pixels sample to the right
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compute box filter parameters.
|
|
||||||
*
|
|
||||||
* @param radius The blur radius.
|
|
||||||
* @returns Parameters for three box filters.
|
|
||||||
**/
|
|
||||||
static QVector<BoxLobes> computeLobes(int radius)
|
|
||||||
{
|
|
||||||
const int blurRadius = calculateBlurRadius(calculateBlurStdDev(radius));
|
|
||||||
const int z = blurRadius / 3;
|
|
||||||
|
|
||||||
int major;
|
|
||||||
int minor;
|
|
||||||
int final;
|
|
||||||
|
|
||||||
switch (blurRadius % 3) {
|
|
||||||
case 0:
|
|
||||||
major = z;
|
|
||||||
minor = z;
|
|
||||||
final = z;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
major = z + 1;
|
|
||||||
minor = z;
|
|
||||||
final = z;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
major = z + 1;
|
|
||||||
minor = z;
|
|
||||||
final = z + 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Q_UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_ASSERT(major + minor + final == blurRadius);
|
|
||||||
|
|
||||||
return {
|
|
||||||
{major, minor},
|
|
||||||
{minor, major},
|
|
||||||
{final, final}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a row with a box filter.
|
|
||||||
*
|
|
||||||
* @param src The start of the row.
|
|
||||||
* @param dst The destination.
|
|
||||||
* @param width The width of the row, in pixels.
|
|
||||||
* @param horizontalStride The number of bytes from one alpha value to the
|
|
||||||
* next alpha value.
|
|
||||||
* @param verticalStride The number of bytes from one row to the next row.
|
|
||||||
* @param lobes Params of the box filter.
|
|
||||||
* @param transposeInput Whether the input is transposed.
|
|
||||||
* @param transposeOutput Whether the output should be transposed.
|
|
||||||
**/
|
|
||||||
static inline void boxBlurRowAlpha(const uint8_t *src, uint8_t *dst, int width, int horizontalStride,
|
|
||||||
int verticalStride, const BoxLobes &lobes, bool transposeInput,
|
|
||||||
bool transposeOutput)
|
|
||||||
{
|
|
||||||
const int inputStep = transposeInput ? verticalStride : horizontalStride;
|
|
||||||
const int outputStep = transposeOutput ? verticalStride : horizontalStride;
|
|
||||||
|
|
||||||
const int boxSize = lobes.left + 1 + lobes.right;
|
|
||||||
const int reciprocal = (1 << 24) / boxSize;
|
|
||||||
|
|
||||||
uint32_t alphaSum = (boxSize + 1) / 2;
|
|
||||||
|
|
||||||
const uint8_t *left = src;
|
|
||||||
const uint8_t *right = src;
|
|
||||||
uint8_t *out = dst;
|
|
||||||
|
|
||||||
const uint8_t firstValue = src[0];
|
|
||||||
const uint8_t lastValue = src[(width - 1) * inputStep];
|
|
||||||
|
|
||||||
alphaSum += firstValue * lobes.left;
|
|
||||||
|
|
||||||
const uint8_t *initEnd = src + (boxSize - lobes.left) * inputStep;
|
|
||||||
while (right < initEnd) {
|
|
||||||
alphaSum += *right;
|
|
||||||
right += inputStep;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t *leftEnd = src + boxSize * inputStep;
|
|
||||||
while (right < leftEnd) {
|
|
||||||
*out = (alphaSum * reciprocal) >> 24;
|
|
||||||
alphaSum += *right - firstValue;
|
|
||||||
right += inputStep;
|
|
||||||
out += outputStep;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t *centerEnd = src + width * inputStep;
|
|
||||||
while (right < centerEnd) {
|
|
||||||
*out = (alphaSum * reciprocal) >> 24;
|
|
||||||
alphaSum += *right - *left;
|
|
||||||
left += inputStep;
|
|
||||||
right += inputStep;
|
|
||||||
out += outputStep;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t *rightEnd = dst + width * outputStep;
|
|
||||||
while (out < rightEnd) {
|
|
||||||
*out = (alphaSum * reciprocal) >> 24;
|
|
||||||
alphaSum += lastValue - *left;
|
|
||||||
left += inputStep;
|
|
||||||
out += outputStep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Blur the alpha channel of a given image.
|
|
||||||
*
|
|
||||||
* @param image The input image.
|
|
||||||
* @param radius The blur radius.
|
|
||||||
* @param rect Specifies what part of the image to blur. If nothing is provided, then
|
|
||||||
* the whole alpha channel of the input image will be blurred.
|
|
||||||
**/
|
|
||||||
static inline void boxBlurAlpha(QImage &image, int radius, const QRect &rect = {})
|
|
||||||
{
|
|
||||||
if (radius < 2) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QVector<BoxLobes> lobes = computeLobes(radius);
|
|
||||||
|
|
||||||
const QRect blurRect = rect.isNull() ? image.rect() : rect;
|
|
||||||
|
|
||||||
const int alphaOffset = QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3;
|
|
||||||
const int width = blurRect.width();
|
|
||||||
const int height = blurRect.height();
|
|
||||||
const int rowStride = image.bytesPerLine();
|
|
||||||
const int pixelStride = image.depth() >> 3;
|
|
||||||
|
|
||||||
const int bufferStride = qMax(width, height) * pixelStride;
|
|
||||||
QScopedPointer<uint8_t, QScopedPointerArrayDeleter<uint8_t> > buf(new uint8_t[2 * bufferStride]);
|
|
||||||
uint8_t *buf1 = buf.data();
|
|
||||||
uint8_t *buf2 = buf1 + bufferStride;
|
|
||||||
|
|
||||||
// Blur the image in horizontal direction.
|
|
||||||
for (int i = 0; i < height; ++i) {
|
|
||||||
uint8_t *row = image.scanLine(blurRect.y() + i) + blurRect.x() * pixelStride + alphaOffset;
|
|
||||||
boxBlurRowAlpha(row, buf1, width, pixelStride, rowStride, lobes[0], false, false);
|
|
||||||
boxBlurRowAlpha(buf1, buf2, width, pixelStride, rowStride, lobes[1], false, false);
|
|
||||||
boxBlurRowAlpha(buf2, row, width, pixelStride, rowStride, lobes[2], false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blur the image in vertical direction.
|
|
||||||
for (int i = 0; i < width; ++i) {
|
|
||||||
uint8_t *column = image.scanLine(blurRect.y()) + (blurRect.x() + i) * pixelStride + alphaOffset;
|
|
||||||
boxBlurRowAlpha(column, buf1, height, pixelStride, rowStride, lobes[0], true, false);
|
|
||||||
boxBlurRowAlpha(buf1, buf2, height, pixelStride, rowStride, lobes[1], false, false);
|
|
||||||
boxBlurRowAlpha(buf2, column, height, pixelStride, rowStride, lobes[2], false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mirrorTopLeftQuadrant(QImage &image)
|
|
||||||
{
|
|
||||||
const int width = image.width();
|
|
||||||
const int height = image.height();
|
|
||||||
|
|
||||||
const int centerX = qCeil(width * 0.5);
|
|
||||||
const int centerY = qCeil(height * 0.5);
|
|
||||||
|
|
||||||
const int alphaOffset = QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3;
|
|
||||||
const int stride = image.depth() >> 3;
|
|
||||||
|
|
||||||
for (int y = 0; y < centerY; ++y) {
|
|
||||||
uint8_t *in = image.scanLine(y) + alphaOffset;
|
|
||||||
uint8_t *out = in + (width - 1) * stride;
|
|
||||||
|
|
||||||
for (int x = 0; x < centerX; ++x, in += stride, out -= stride) {
|
|
||||||
*out = *in;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int y = 0; y < centerY; ++y) {
|
|
||||||
const uint8_t *in = image.scanLine(y) + alphaOffset;
|
|
||||||
uint8_t *out = image.scanLine(width - y - 1) + alphaOffset;
|
|
||||||
|
|
||||||
for (int x = 0; x < width; ++x, in += stride, out += stride) {
|
|
||||||
*out = *in;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void renderShadow(QPainter *painter, const QRect &rect, qreal borderRadius, const QPoint &offset, int radius, const QColor &color)
|
|
||||||
{
|
|
||||||
const QSize inflation = calculateBlurExtent(radius);
|
|
||||||
const QSize size = rect.size() + 2 * inflation;
|
|
||||||
|
|
||||||
const qreal dpr = painter->device()->devicePixelRatioF();
|
|
||||||
|
|
||||||
QImage shadow(size * dpr, QImage::Format_ARGB32_Premultiplied);
|
|
||||||
shadow.setDevicePixelRatio(dpr);
|
|
||||||
shadow.fill(Qt::transparent);
|
|
||||||
|
|
||||||
QRect boxRect(QPoint(0, 0), rect.size());
|
|
||||||
boxRect.moveCenter(QRect(QPoint(0, 0), size).center());
|
|
||||||
|
|
||||||
const qreal xRadius = 2.0 * borderRadius / boxRect.width();
|
|
||||||
const qreal yRadius = 2.0 * borderRadius / boxRect.height();
|
|
||||||
|
|
||||||
QPainter shadowPainter;
|
|
||||||
shadowPainter.begin(&shadow);
|
|
||||||
shadowPainter.setRenderHint(QPainter::Antialiasing);
|
|
||||||
shadowPainter.setPen(Qt::NoPen);
|
|
||||||
shadowPainter.setBrush(Qt::black);
|
|
||||||
shadowPainter.drawRoundedRect(boxRect, xRadius, yRadius);
|
|
||||||
shadowPainter.end();
|
|
||||||
|
|
||||||
// Because the shadow texture is symmetrical, that's enough to blur
|
|
||||||
// only the top-left quadrant and then mirror it.
|
|
||||||
const QRect blurRect(0, 0, qCeil(shadow.width() * 0.5), qCeil(shadow.height() * 0.5));
|
|
||||||
const int scaledRadius = qRound(radius * dpr);
|
|
||||||
boxBlurAlpha(shadow, scaledRadius, blurRect);
|
|
||||||
mirrorTopLeftQuadrant(shadow);
|
|
||||||
|
|
||||||
// Give the shadow a tint of the desired color.
|
|
||||||
shadowPainter.begin(&shadow);
|
|
||||||
shadowPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
|
||||||
shadowPainter.fillRect(shadow.rect(), color);
|
|
||||||
shadowPainter.end();
|
|
||||||
|
|
||||||
// Actually, present the shadow.
|
|
||||||
QRect shadowRect = shadow.rect();
|
|
||||||
shadowRect.setSize(shadowRect.size() / dpr);
|
|
||||||
shadowRect.moveCenter(rect.center() + offset);
|
|
||||||
painter->drawImage(shadowRect, shadow);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BoxShadowRenderer::setBoxSize(const QSize &size)
|
|
||||||
{
|
|
||||||
m_boxSize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BoxShadowRenderer::setBorderRadius(qreal radius)
|
|
||||||
{
|
|
||||||
m_borderRadius = radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BoxShadowRenderer::setDevicePixelRatio(qreal dpr)
|
|
||||||
{
|
|
||||||
m_dpr = dpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BoxShadowRenderer::addShadow(const QPoint &offset, int radius, const QColor &color)
|
|
||||||
{
|
|
||||||
Shadow shadow = {};
|
|
||||||
shadow.offset = offset;
|
|
||||||
shadow.radius = radius;
|
|
||||||
shadow.color = color;
|
|
||||||
m_shadows.append(shadow);
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage BoxShadowRenderer::render() const
|
|
||||||
{
|
|
||||||
if (m_shadows.isEmpty()) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize canvasSize;
|
|
||||||
for (const Shadow &shadow : qAsConst(m_shadows)) {
|
|
||||||
canvasSize = canvasSize.expandedTo(
|
|
||||||
calculateMinimumShadowTextureSize(m_boxSize, shadow.radius, shadow.offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage canvas(canvasSize * m_dpr, QImage::Format_ARGB32_Premultiplied);
|
|
||||||
canvas.setDevicePixelRatio(m_dpr);
|
|
||||||
canvas.fill(Qt::transparent);
|
|
||||||
|
|
||||||
QRect boxRect(QPoint(0, 0), m_boxSize);
|
|
||||||
boxRect.moveCenter(QRect(QPoint(0, 0), canvasSize).center());
|
|
||||||
|
|
||||||
QPainter painter(&canvas);
|
|
||||||
for (const Shadow &shadow : qAsConst(m_shadows)) {
|
|
||||||
renderShadow(&painter, boxRect, m_borderRadius, shadow.offset, shadow.radius, shadow.color);
|
|
||||||
}
|
|
||||||
painter.end();
|
|
||||||
|
|
||||||
return canvas;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize BoxShadowRenderer::calculateMinimumBoxSize(int radius)
|
|
||||||
{
|
|
||||||
const QSize blurExtent = calculateBlurExtent(radius);
|
|
||||||
return 2 * blurExtent + QSize(1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize BoxShadowRenderer::calculateMinimumShadowTextureSize(const QSize &boxSize, int radius, const QPoint &offset)
|
|
||||||
{
|
|
||||||
return boxSize + 2 * calculateBlurExtent(radius) + QSize(qAbs(offset.x()), qAbs(offset.y()));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Breeze
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// own
|
|
||||||
#include "breezecommon_export.h"
|
|
||||||
|
|
||||||
// Qt
|
|
||||||
#include <QColor>
|
|
||||||
#include <QImage>
|
|
||||||
#include <QPoint>
|
|
||||||
#include <QSize>
|
|
||||||
|
|
||||||
namespace Breeze
|
|
||||||
{
|
|
||||||
|
|
||||||
class BREEZECOMMON_EXPORT BoxShadowRenderer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Compiler generated constructors & destructor are fine.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the size of the box.
|
|
||||||
* @param size The size of the box.
|
|
||||||
**/
|
|
||||||
void setBoxSize(const QSize &size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the radius of box' corners.
|
|
||||||
* @param radius The border radius, in pixels.
|
|
||||||
**/
|
|
||||||
void setBorderRadius(qreal radius);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the device pixel ratio of the resulting shadow texture.
|
|
||||||
* @param dpr The device pixel ratio.
|
|
||||||
**/
|
|
||||||
void setDevicePixelRatio(qreal dpr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a shadow.
|
|
||||||
* @param offset The offset of the shadow.
|
|
||||||
* @param radius The blur radius.
|
|
||||||
* @param color The color of the shadow.
|
|
||||||
**/
|
|
||||||
void addShadow(const QPoint &offset, int radius, const QColor &color);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render the shadow.
|
|
||||||
**/
|
|
||||||
QImage render() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the minimum size of the box.
|
|
||||||
*
|
|
||||||
* This helper computes the minimum size of the box so the shadow behind it has
|
|
||||||
* full its strength.
|
|
||||||
*
|
|
||||||
* @param radius The blur radius of the shadow.
|
|
||||||
**/
|
|
||||||
static QSize calculateMinimumBoxSize(int radius);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the minimum size of the shadow texture.
|
|
||||||
*
|
|
||||||
* This helper computes the minimum size of the resulting texture so the shadow
|
|
||||||
* is not clipped.
|
|
||||||
*
|
|
||||||
* @param boxSize The size of the box.
|
|
||||||
* @param radius The blur radius.
|
|
||||||
* @param offset The offset of the shadow.
|
|
||||||
**/
|
|
||||||
static QSize calculateMinimumShadowTextureSize(const QSize &boxSize, int radius, const QPoint &offset);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QSize m_boxSize;
|
|
||||||
qreal m_borderRadius = 0.0;
|
|
||||||
qreal m_dpr = 1.0;
|
|
||||||
|
|
||||||
struct Shadow {
|
|
||||||
QPoint offset;
|
|
||||||
int radius;
|
|
||||||
QColor color;
|
|
||||||
};
|
|
||||||
|
|
||||||
QVector<Shadow> m_shadows;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Breeze
|
|
||||||
2
Makefile
2
Makefile
@ -1,4 +1,4 @@
|
|||||||
SUBDIRS=emblems kali-logos KDE-themes
|
SUBDIRS=emblems kali-logos
|
||||||
DESKTOP_BACKGROUND=kali-nova
|
DESKTOP_BACKGROUND=kali-nova
|
||||||
LOGIN_BACKGROUND=kali-contours
|
LOGIN_BACKGROUND=kali-contours
|
||||||
|
|
||||||
|
|||||||
19
debian/control
vendored
19
debian/control
vendored
@ -3,17 +3,8 @@ Section: misc
|
|||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Kali Developers <devel@kali.org>
|
Maintainer: Kali Developers <devel@kali.org>
|
||||||
Uploaders: Daniel Ruiz de Alegría <daniel@drasite.com>, Raphaël Hertzog <raphael@offensive-security.com>
|
Uploaders: Daniel Ruiz de Alegría <daniel@drasite.com>, Raphaël Hertzog <raphael@offensive-security.com>
|
||||||
Build-Depends: cmake,
|
Build-Depends:
|
||||||
debhelper-compat (= 12),
|
debhelper-compat (= 12),
|
||||||
extra-cmake-modules,
|
|
||||||
libkdecorations2-dev,
|
|
||||||
libkf5configwidgets-dev,
|
|
||||||
libkf5coreaddons-dev,
|
|
||||||
libkf5guiaddons-dev,
|
|
||||||
libkf5i18n-dev,
|
|
||||||
libkf5iconthemes-dev,
|
|
||||||
libkf5windowsystem-dev,
|
|
||||||
libqt5x11extras5-dev,
|
|
||||||
librsvg2-bin,
|
librsvg2-bin,
|
||||||
optipng,
|
optipng,
|
||||||
Standards-Version: 4.5.1
|
Standards-Version: 4.5.1
|
||||||
@ -87,14 +78,6 @@ Description: Configure all desktops to use the Kali theme
|
|||||||
provides configuration files and other settings for each desktop so that
|
provides configuration files and other settings for each desktop so that
|
||||||
they use the Kali theme by default.
|
they use the Kali theme by default.
|
||||||
|
|
||||||
Package: kwin-style-kali
|
|
||||||
Architecture: any
|
|
||||||
Depends:
|
|
||||||
${misc:Depends},
|
|
||||||
${shlibs:Depends}
|
|
||||||
Description: Kali theme for KWin
|
|
||||||
Kali's window manager theme for KDE Plasma 5 desktop
|
|
||||||
|
|
||||||
Package: gnome-theme-kali
|
Package: gnome-theme-kali
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Depends: kali-themes,
|
Depends: kali-themes,
|
||||||
|
|||||||
2
debian/kwin-style-kali.install
vendored
2
debian/kwin-style-kali.install
vendored
@ -1,2 +0,0 @@
|
|||||||
# Created by "make install"
|
|
||||||
usr/lib/*/qt5/
|
|
||||||
Loading…
x
Reference in New Issue
Block a user