1
0
mirror of https://github.com/KDE/latte-dock.git synced 2025-01-10 09:18:13 +03:00

support drawing panel shadows outside dock window

--this is set by default only in case of Always Visible,
zoom factor 1.0, Justify alignment and maximum panel
thickness
This commit is contained in:
Michail Vourlakos 2017-01-31 21:25:00 +02:00
parent f9a2226457
commit 09629b774b
13 changed files with 1180 additions and 63 deletions

View File

@ -24,7 +24,7 @@ find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
Plasma PlasmaQuick WindowSystem Declarative Plasma PlasmaQuick WindowSystem Declarative
I18n CoreAddons XmlGui DBusAddons IconThemes) I18n CoreAddons XmlGui DBusAddons IconThemes Wayland)
FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt) FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt)

View File

@ -1,7 +1,3 @@
find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE COMPONENTS Quick Qml)
find_package(KF5I18n NO_MODULE)
find_package(KF5Activities REQUIRED)
include(KDEInstallDirs) include(KDEInstallDirs)
include(KDECMakeSettings) include(KDECMakeSettings)
#include(KDECompilerSettings NO_POLICY_SCOPE) #include(KDECompilerSettings NO_POLICY_SCOPE)
@ -13,6 +9,32 @@ include(ECMOptionalAddSubdirectory)
include(ECMQtDeclareLoggingCategory) include(ECMQtDeclareLoggingCategory)
include(KDEPackageAppTemplates) include(KDEPackageAppTemplates)
find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE COMPONENTS Quick Qml)
find_package(KF5I18n NO_MODULE)
find_package(KF5Activities REQUIRED)
find_package(X11 REQUIRED)
set_package_properties(X11 PROPERTIES DESCRIPTION "X11 libraries"
URL "http://www.x.org"
TYPE OPTIONAL
PURPOSE "Required for building the X11 based workspace")
if(X11_FOUND)
find_package(XCB MODULE REQUIRED COMPONENTS XCB RANDR)
set_package_properties(XCB PROPERTIES TYPE REQUIRED)
if(NOT X11_SM_FOUND)
message(FATAL_ERROR "\nThe X11 Session Management (SM) development package could not be found.\nPlease install libSM.\n")
endif(NOT X11_SM_FOUND)
find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED COMPONENTS X11Extras)
endif()
if(X11_FOUND AND XCB_XCB_FOUND)
set(HAVE_X11 true)
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-latte.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-latte.h)
set(lattedock-app_SRCS set(lattedock-app_SRCS
../liblattedock/dock.cpp ../liblattedock/dock.cpp
../liblattedock/windowsystem.cpp ../liblattedock/windowsystem.cpp
@ -25,6 +47,7 @@ set(lattedock-app_SRCS
dockview.cpp dockview.cpp
dockconfigview.cpp dockconfigview.cpp
packageplugins/shell/dockpackage.cpp packageplugins/shell/dockpackage.cpp
panelshadows.cpp
main.cpp main.cpp
) )
@ -48,8 +71,13 @@ target_link_libraries(
KF5::Activities KF5::Activities
KF5::QuickAddons KF5::QuickAddons
KF5::WindowSystem KF5::WindowSystem
KF5::WaylandClient
) )
if(HAVE_X11)
target_link_libraries(latte-dock ${X11_LIBRARIES} ${XCB_LIBRARIES} )
endif()
install(TARGETS latte-dock ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS latte-dock ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
#even if hidden, the desktop file is needed anyways for kdbusservice::unique #even if hidden, the desktop file is needed anyways for kdbusservice::unique
install(FILES latte-dock.desktop DESTINATION ${KDE_INSTALL_APPDIR}) install(FILES latte-dock.desktop DESTINATION ${KDE_INSTALL_APPDIR})

1
app/config-latte.h.cmake Normal file
View File

@ -0,0 +1 @@
#cmakedefine01 HAVE_X11

View File

@ -22,6 +22,7 @@
#include "dockconfigview.h" #include "dockconfigview.h"
#include "dockcorona.h" #include "dockcorona.h"
#include "visibilitymanager.h" #include "visibilitymanager.h"
#include "panelshadows_p.h"
#include "../liblattedock/extras.h" #include "../liblattedock/extras.h"
#include "../liblattedock/windowsystem.h" #include "../liblattedock/windowsystem.h"
@ -113,6 +114,8 @@ void DockView::init()
connect(this, &QQuickWindow::widthChanged, this, &DockView::widthChanged); connect(this, &QQuickWindow::widthChanged, this, &DockView::widthChanged);
connect(this, &QQuickWindow::heightChanged, this, &DockView::heightChanged); connect(this, &QQuickWindow::heightChanged, this, &DockView::heightChanged);
connect(this, &DockView::localDockGeometryChanged, this, &DockView::updateAbsDockGeometry); connect(this, &DockView::localDockGeometryChanged, this, &DockView::updateAbsDockGeometry);
connect(this, &DockView::drawShadowsChanged, this, &DockView::syncGeometry);
connect(this, &DockView::maxLengthChanged, this, &DockView::syncGeometry);
connect(this, &DockView::locationChanged, this, [&]() { connect(this, &DockView::locationChanged, this, [&]() {
updateFormFactor(); updateFormFactor();
syncGeometry(); syncGeometry();
@ -232,12 +235,24 @@ void DockView::resizeWindow()
QSize screenSize = screen()->size(); QSize screenSize = screen()->size();
if (formFactor() == Plasma::Types::Vertical) { if (formFactor() == Plasma::Types::Vertical) {
const QSize size{maxThickness(), screenSize.height()}; QSize size{maxThickness(), screenSize.height()};
if (m_drawShadows) {
size.setWidth(normalThickness());
size.setHeight(maxLength() * screenSize.height());
}
setMinimumSize(size); setMinimumSize(size);
setMaximumSize(size); setMaximumSize(size);
resize(size); resize(size);
} else { } else {
const QSize size{screenSize.width(), maxThickness()}; QSize size{screenSize.width(), maxThickness()};
if (m_drawShadows) {
size.setWidth(maxLength() * screenSize.width());
size.setHeight(normalThickness());
}
setMinimumSize(size); setMinimumSize(size);
setMaximumSize(size); setMaximumSize(size);
resize(size); resize(size);
@ -251,6 +266,7 @@ void DockView::setLocalDockGeometry(const QRect &geometry)
} }
m_localDockGeometry = geometry; m_localDockGeometry = geometry;
emit localDockGeometryChanged(); emit localDockGeometryChanged();
} }
@ -272,19 +288,51 @@ void DockView::updatePosition()
QPoint position; QPoint position;
position = {0, 0}; position = {0, 0};
int maxLengthWidth = maxLength() * screenGeometry.width();
int maxLengthHeight = maxLength() * screenGeometry.height();
int cleanThickness = normalThickness() - shadow();
switch (location()) { switch (location()) {
case Plasma::Types::TopEdge: case Plasma::Types::TopEdge:
if (m_drawShadows) {
position = {screenGeometry.x() + (screenGeometry.width() / 2 - maxLengthWidth / 2), screenGeometry.y()};
} else {
position = {screenGeometry.x(), screenGeometry.y()}; position = {screenGeometry.x(), screenGeometry.y()};
}
break; break;
case Plasma::Types::BottomEdge: case Plasma::Types::BottomEdge:
if (m_drawShadows) {
position = {screenGeometry.x() + (screenGeometry.width() / 2 - maxLengthWidth / 2),
screenGeometry.y() + screenGeometry.height() - cleanThickness
};
} else {
position = {screenGeometry.x(), screenGeometry.y() + screenGeometry.height() - height()}; position = {screenGeometry.x(), screenGeometry.y() + screenGeometry.height() - height()};
}
break; break;
case Plasma::Types::RightEdge: case Plasma::Types::RightEdge:
if (m_drawShadows && !mask().isNull()) {
position = {screenGeometry.x() + screenGeometry.width() - cleanThickness,
screenGeometry.y() + (screenGeometry.height() / 2 - maxLengthHeight / 2)
};
} else {
position = {screenGeometry.x() + screenGeometry.width() - width(), screenGeometry.y()}; position = {screenGeometry.x() + screenGeometry.width() - width(), screenGeometry.y()};
}
break; break;
case Plasma::Types::LeftEdge: case Plasma::Types::LeftEdge:
if (m_drawShadows && !mask().isNull()) {
position = {screenGeometry.x(), screenGeometry.y() + (screenGeometry.height() / 2 - maxLengthHeight / 2)};
} else {
position = {screenGeometry.x(), screenGeometry.y()}; position = {screenGeometry.x(), screenGeometry.y()};
}
break; break;
default: default:
qWarning() << "wrong location, couldn't update the panel position" qWarning() << "wrong location, couldn't update the panel position"
<< location(); << location();
@ -295,6 +343,7 @@ void DockView::updatePosition()
inline void DockView::syncGeometry() inline void DockView::syncGeometry()
{ {
updateEnabledBorders();
resizeWindow(); resizeWindow();
updatePosition(); updatePosition();
updateAbsDockGeometry(); updateAbsDockGeometry();
@ -367,6 +416,46 @@ void DockView::updateFormFactor()
} }
} }
bool DockView::drawShadows() const
{
return m_drawShadows;
}
void DockView::setDrawShadows(bool draw)
{
if (m_drawShadows == draw) {
return;
}
m_drawShadows = draw;
if (m_drawShadows) {
PanelShadows::self()->addWindow(this, enabledBorders());
} else {
PanelShadows::self()->removeWindow(this);
m_enabledBorders = Plasma::FrameSvg::AllBorders;
emit enabledBordersChanged();
}
emit drawShadowsChanged();
}
float DockView::maxLength() const
{
return m_maxLength;
}
void DockView::setMaxLength(float length)
{
if (m_maxLength == length) {
return;
}
m_maxLength = length;
emit maxLengthChanged();
}
int DockView::maxThickness() const int DockView::maxThickness() const
{ {
return m_maxThickness; return m_maxThickness;
@ -409,6 +498,11 @@ void DockView::setShadow(int shadow)
return; return;
m_shadow = shadow; m_shadow = shadow;
if (m_drawShadows) {
syncGeometry();
}
emit shadowChanged(); emit shadowChanged();
} }
@ -442,6 +536,7 @@ VisibilityManager *DockView::visibility()
bool DockView::event(QEvent *e) bool DockView::event(QEvent *e)
{ {
emit eventTriggered(e); emit eventTriggered(e);
return ContainmentView::event(e); return ContainmentView::event(e);
} }
@ -757,7 +852,6 @@ void DockView::addAppletActions(QMenu *desktopMenu, Plasma::Applet *applet, QEve
} }
} }
void DockView::addContainmentActions(QMenu *desktopMenu, QEvent *event) void DockView::addContainmentActions(QMenu *desktopMenu, QEvent *event)
{ {
if (!containment()) { if (!containment()) {
@ -818,5 +912,80 @@ Plasma::Containment *DockView::containmentById(int id)
//!END overriding context menus behavior //!END overriding context menus behavior
//!BEGIN draw panel shadows outside the dock window
Plasma::FrameSvg::EnabledBorders DockView::enabledBorders() const
{
return m_enabledBorders;
}
void DockView::updateEnabledBorders()
{
// qDebug() << "draw shadow!!!! :" << m_drawShadows;
if (!screen()) {
return;
}
if (!m_drawShadows) {
PanelShadows::self()->removeWindow(this);
return;
}
Plasma::FrameSvg::EnabledBorders borders = Plasma::FrameSvg::AllBorders;
if (!m_drawShadows) {
borders = Plasma::FrameSvg::NoBorder;
} else {
switch (location()) {
case Plasma::Types::TopEdge:
borders &= ~Plasma::FrameSvg::TopBorder;
break;
case Plasma::Types::LeftEdge:
borders &= ~Plasma::FrameSvg::LeftBorder;
break;
case Plasma::Types::RightEdge:
borders &= ~Plasma::FrameSvg::RightBorder;
break;
case Plasma::Types::BottomEdge:
borders &= ~Plasma::FrameSvg::BottomBorder;
break;
default:
break;
}
if (x() <= screen()->geometry().x()) {
borders &= ~Plasma::FrameSvg::LeftBorder;
}
if (x() + width() >= screen()->geometry().x() + screen()->geometry().width()) {
borders &= ~Plasma::FrameSvg::RightBorder;
}
if (y() <= screen()->geometry().y()) {
borders &= ~Plasma::FrameSvg::TopBorder;
}
if (y() + height() >= screen()->geometry().y() + screen()->geometry().height()) {
borders &= ~Plasma::FrameSvg::BottomBorder;
}
}
PanelShadows::self()->setEnabledBorders(this, borders);
if (m_enabledBorders != borders) {
PanelShadows::self()->setEnabledBorders(this, borders);
m_enabledBorders = borders;
emit enabledBordersChanged();
}
}
//!END draw panel shadows outside the dock window
} }
//!END namespace //!END namespace

View File

@ -42,6 +42,7 @@ namespace Latte {
class DockView : public PlasmaQuick::ContainmentView { class DockView : public PlasmaQuick::ContainmentView {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool drawShadows READ drawShadows WRITE setDrawShadows NOTIFY drawShadowsChanged)
Q_PROPERTY(int docksCount READ docksCount NOTIFY docksCountChanged) Q_PROPERTY(int docksCount READ docksCount NOTIFY docksCountChanged)
Q_PROPERTY(int width READ width NOTIFY widthChanged) Q_PROPERTY(int width READ width NOTIFY widthChanged)
@ -51,6 +52,10 @@ class DockView : public PlasmaQuick::ContainmentView {
Q_PROPERTY(int shadow READ shadow WRITE setShadow NOTIFY shadowChanged) Q_PROPERTY(int shadow READ shadow WRITE setShadow NOTIFY shadowChanged)
Q_PROPERTY(QStringList debugFlags READ debugFlags NOTIFY debugFlagsChanged) Q_PROPERTY(QStringList debugFlags READ debugFlags NOTIFY debugFlagsChanged)
Q_PROPERTY(float maxLength READ maxLength WRITE setMaxLength NOTIFY maxLengthChanged)
Q_PROPERTY(Plasma::FrameSvg::EnabledBorders enabledBorders READ enabledBorders NOTIFY enabledBordersChanged)
Q_PROPERTY(QRect maskArea READ maskArea WRITE setMaskArea NOTIFY maskAreaChanged) Q_PROPERTY(QRect maskArea READ maskArea WRITE setMaskArea NOTIFY maskAreaChanged)
Q_PROPERTY(VisibilityManager *visibility READ visibility NOTIFY visibilityChanged) Q_PROPERTY(VisibilityManager *visibility READ visibility NOTIFY visibilityChanged)
Q_PROPERTY(QQmlListProperty<QScreen> screens READ screens) Q_PROPERTY(QQmlListProperty<QScreen> screens READ screens)
@ -71,6 +76,12 @@ public:
int docksCount() const; int docksCount() const;
bool drawShadows() const;
void setDrawShadows(bool draw);
float maxLength() const;
void setMaxLength(float length);
int maxThickness() const; int maxThickness() const;
void setMaxThickness(int thickness); void setMaxThickness(int thickness);
@ -83,6 +94,8 @@ public:
QRect maskArea() const; QRect maskArea() const;
void setMaskArea(QRect area); void setMaskArea(QRect area);
Plasma::FrameSvg::EnabledBorders enabledBorders() const;
QStringList debugFlags() const; QStringList debugFlags() const;
VisibilityManager *visibility(); VisibilityManager *visibility();
@ -99,6 +112,7 @@ public slots:
Q_INVOKABLE QVariantList containmentActions(); Q_INVOKABLE QVariantList containmentActions();
Q_INVOKABLE void setLocalDockGeometry(const QRect &geometry); Q_INVOKABLE void setLocalDockGeometry(const QRect &geometry);
Q_INVOKABLE bool tasksPresent(); Q_INVOKABLE bool tasksPresent();
Q_INVOKABLE void updateEnabledBorders();
Q_INVOKABLE void closeApplication(); Q_INVOKABLE void closeApplication();
@ -118,8 +132,11 @@ signals:
void debugFlagsChanged(); void debugFlagsChanged();
void dockLocationChanged(); void dockLocationChanged();
void docksCountChanged(); void docksCountChanged();
void drawShadowsChanged();
void enabledBordersChanged();
void widthChanged(); void widthChanged();
void heightChanged(); void heightChanged();
void maxLengthChanged();
void maxThicknessChanged(); void maxThicknessChanged();
void normalThicknessChanged(); void normalThicknessChanged();
void visibilityChanged(); void visibilityChanged();
@ -143,15 +160,20 @@ private:
private: private:
Plasma::Containment *containmentById(int id); Plasma::Containment *containmentById(int id);
bool m_drawShadows{false};
int m_maxThickness{24}; int m_maxThickness{24};
int m_normalThickness{24}; int m_normalThickness{24};
int m_shadow{0}; int m_shadow{0};
float m_maxLength{1};
QRect m_localDockGeometry; QRect m_localDockGeometry;
QRect m_maskArea; QRect m_maskArea;
QMenu *m_contextMenu; QMenu *m_contextMenu;
QPointer<PlasmaQuick::ConfigView> m_configView; QPointer<PlasmaQuick::ConfigView> m_configView;
QPointer<VisibilityManager> m_visibility; QPointer<VisibilityManager> m_visibility;
//only for the mask, not to actually paint
Plasma::FrameSvg::EnabledBorders m_enabledBorders = Plasma::FrameSvg::AllBorders;
}; };
} }

750
app/panelshadows.cpp Normal file
View File

@ -0,0 +1,750 @@
/*
* Copyright 2011 by Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "panelshadows_p.h"
#include <QWindow>
#include <QPainter>
#include <config-latte.h>
#include <KWindowSystem>
#if HAVE_X11
#include <QX11Info>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>
#include <fixx11h.h>
#endif
#include <KWayland/Client/connection_thread.h>
#include <KWayland/Client/registry.h>
#include <KWayland/Client/shadow.h>
#include <KWayland/Client/shm_pool.h>
#include <KWayland/Client/surface.h>
#include <qdebug.h>
class PanelShadows::Private {
public:
Private(PanelShadows *shadows)
: q(shadows)
#if HAVE_X11
, _connection(0x0),
_gc(0x0)
, m_isX11(KWindowSystem::isPlatformX11())
#endif
{
setupWaylandIntegration();
}
~Private() {
// Do not call clearPixmaps() from here: it creates new QPixmap(),
// which causes a crash when application is stopping.
freeX11Pixmaps();
}
void freeX11Pixmaps();
void freeWaylandBuffers();
void clearPixmaps();
void setupPixmaps();
Qt::HANDLE createPixmap(const QPixmap &source);
void initPixmap(const QString &element);
QPixmap initEmptyPixmap(const QSize &size);
void updateShadow(const QWindow *window, Plasma::FrameSvg::EnabledBorders);
void updateShadowX11(const QWindow *window, Plasma::FrameSvg::EnabledBorders);
void updateShadowWayland(const QWindow *window, Plasma::FrameSvg::EnabledBorders);
void clearShadow(const QWindow *window);
void clearShadowX11(const QWindow *window);
void clearShadowWayland(const QWindow *window);
void updateShadows();
void windowDestroyed(QObject *deletedObject);
void setupData(Plasma::FrameSvg::EnabledBorders enabledBorders);
void setupWaylandIntegration();
PanelShadows *q;
QList<QPixmap> m_shadowPixmaps;
QPixmap m_emptyCornerPix;
QPixmap m_emptyCornerLeftPix;
QPixmap m_emptyCornerTopPix;
QPixmap m_emptyCornerRightPix;
QPixmap m_emptyCornerBottomPix;
QPixmap m_emptyVerticalPix;
QPixmap m_emptyHorizontalPix;
#if HAVE_X11
//! xcb connection
xcb_connection_t *_connection;
//! graphical context
xcb_gcontext_t _gc;
bool m_isX11;
#endif
struct Wayland {
KWayland::Client::ShadowManager *manager = nullptr;
KWayland::Client::ShmPool *shmPool = nullptr;
QList<KWayland::Client::Buffer::Ptr> shadowBuffers;
};
Wayland m_wayland;
QHash<Plasma::FrameSvg::EnabledBorders, QVector<unsigned long>> data;
QHash<const QWindow *, Plasma::FrameSvg::EnabledBorders> m_windows;
};
class PanelShadowsSingleton {
public:
PanelShadowsSingleton() {
}
PanelShadows self;
};
Q_GLOBAL_STATIC(PanelShadowsSingleton, privatePanelShadowsSelf)
PanelShadows::PanelShadows(QObject *parent, const QString &prefix)
: Plasma::Svg(parent),
d(new Private(this))
{
setImagePath(prefix);
connect(this, SIGNAL(repaintNeeded()), this, SLOT(updateShadows()));
}
PanelShadows::~PanelShadows()
{
delete d;
}
PanelShadows *PanelShadows::self()
{
return &privatePanelShadowsSelf->self;
}
void PanelShadows::addWindow(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
{
if (!window) {
return;
}
d->m_windows[window] = enabledBorders;
d->updateShadow(window, enabledBorders);
connect(window, SIGNAL(destroyed(QObject *)),
this, SLOT(windowDestroyed(QObject *)), Qt::UniqueConnection);
}
void PanelShadows::removeWindow(const QWindow *window)
{
if (!d->m_windows.contains(window)) {
return;
}
d->m_windows.remove(window);
disconnect(window, 0, this, 0);
d->clearShadow(window);
if (d->m_windows.isEmpty()) {
d->clearPixmaps();
}
}
void PanelShadows::setEnabledBorders(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
{
if (!window || !d->m_windows.contains(window)) {
return;
}
d->updateShadow(window, enabledBorders);
}
void PanelShadows::Private::windowDestroyed(QObject *deletedObject)
{
m_windows.remove(static_cast<QWindow *>(deletedObject));
if (m_windows.isEmpty()) {
clearPixmaps();
}
}
void PanelShadows::Private::updateShadows()
{
setupPixmaps();
QHash<const QWindow *, Plasma::FrameSvg::EnabledBorders>::const_iterator i;
for (i = m_windows.constBegin(); i != m_windows.constEnd(); ++i) {
updateShadow(i.key(), i.value());
}
}
Qt::HANDLE PanelShadows::Private::createPixmap(const QPixmap &source)
{
// do nothing for invalid pixmaps
if (source.isNull()) return 0;
/*
in some cases, pixmap handle is invalid. This is the case notably
when Qt uses to RasterEngine. In this case, we create an X11 Pixmap
explicitly and draw the source pixmap on it.
*/
#if HAVE_X11
if (!m_isX11) {
return 0;
}
// check connection
if (!_connection) _connection = QX11Info::connection();
const int width(source.width());
const int height(source.height());
// create X11 pixmap
Pixmap pixmap = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), width, height, 32);
// check gc
if (!_gc) {
_gc = xcb_generate_id(_connection);
xcb_create_gc(_connection, _gc, pixmap, 0, 0x0);
}
// // create explicitly shared QPixmap from it
// QPixmap dest( QPixmap::fromX11Pixmap( pixmap, QPixmap::ExplicitlyShared ) );
//
// // create surface for pixmap
// {
// QPainter painter( &dest );
// painter.setCompositionMode( QPainter::CompositionMode_Source );
// painter.drawPixmap( 0, 0, source );
// }
//
//
// return pixmap;
QImage image(source.toImage());
xcb_put_image(
_connection, XCB_IMAGE_FORMAT_Z_PIXMAP, pixmap, _gc,
image.width(), image.height(), 0, 0,
0, 32,
image.byteCount(), image.constBits());
return (Qt::HANDLE)pixmap;
#else
return 0;
#endif
}
void PanelShadows::Private::initPixmap(const QString &element)
{
m_shadowPixmaps << q->pixmap(element);
}
QPixmap PanelShadows::Private::initEmptyPixmap(const QSize &size)
{
#if HAVE_X11
if (!m_isX11) {
return QPixmap();
}
QPixmap tempEmptyPix(size);
if (!size.isEmpty()) {
tempEmptyPix.fill(Qt::transparent);
}
return tempEmptyPix;
#else
Q_UNUSED(size)
return QPixmap();
#endif
}
void PanelShadows::Private::setupPixmaps()
{
clearPixmaps();
initPixmap(QStringLiteral("shadow-top"));
initPixmap(QStringLiteral("shadow-topright"));
initPixmap(QStringLiteral("shadow-right"));
initPixmap(QStringLiteral("shadow-bottomright"));
initPixmap(QStringLiteral("shadow-bottom"));
initPixmap(QStringLiteral("shadow-bottomleft"));
initPixmap(QStringLiteral("shadow-left"));
initPixmap(QStringLiteral("shadow-topleft"));
m_emptyCornerPix = initEmptyPixmap(QSize(1, 1));
m_emptyCornerLeftPix = initEmptyPixmap(QSize(q->elementSize(QStringLiteral("shadow-topleft")).width(), 1));
m_emptyCornerTopPix = initEmptyPixmap(QSize(1, q->elementSize(QStringLiteral("shadow-topleft")).height()));
m_emptyCornerRightPix = initEmptyPixmap(QSize(q->elementSize(QStringLiteral("shadow-bottomright")).width(), 1));
m_emptyCornerBottomPix = initEmptyPixmap(QSize(1, q->elementSize(QStringLiteral("shadow-bottomright")).height()));
m_emptyVerticalPix = initEmptyPixmap(QSize(1, q->elementSize(QStringLiteral("shadow-left")).height()));
m_emptyHorizontalPix = initEmptyPixmap(QSize(q->elementSize(QStringLiteral("shadow-top")).width(), 1));
if (m_wayland.shmPool) {
for (auto it = m_shadowPixmaps.constBegin(); it != m_shadowPixmaps.constEnd(); ++it) {
m_wayland.shadowBuffers << m_wayland.shmPool->createBuffer(it->toImage());
}
}
}
void PanelShadows::Private::setupData(Plasma::FrameSvg::EnabledBorders enabledBorders)
{
#if HAVE_X11
if (!m_isX11) {
return;
}
//shadow-top
if (enabledBorders & Plasma::FrameSvg::TopBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[0]));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyHorizontalPix));
}
//shadow-topright
if (enabledBorders & Plasma::FrameSvg::TopBorder &&
enabledBorders & Plasma::FrameSvg::RightBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[1]));
} else if (enabledBorders & Plasma::FrameSvg::TopBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerTopPix));
} else if (enabledBorders & Plasma::FrameSvg::RightBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerRightPix));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerPix));
}
//shadow-right
if (enabledBorders & Plasma::FrameSvg::RightBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[2]));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyVerticalPix));
}
//shadow-bottomright
if (enabledBorders & Plasma::FrameSvg::BottomBorder &&
enabledBorders & Plasma::FrameSvg::RightBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[3]));
} else if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerBottomPix));
} else if (enabledBorders & Plasma::FrameSvg::RightBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerRightPix));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerPix));
}
//shadow-bottom
if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[4]));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyHorizontalPix));
}
//shadow-bottomleft
if (enabledBorders & Plasma::FrameSvg::BottomBorder &&
enabledBorders & Plasma::FrameSvg::LeftBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[5]));
} else if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerBottomPix));
} else if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerLeftPix));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerPix));
}
//shadow-left
if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[6]));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyVerticalPix));
}
//shadow-topleft
if (enabledBorders & Plasma::FrameSvg::TopBorder &&
enabledBorders & Plasma::FrameSvg::LeftBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_shadowPixmaps[7]));
} else if (enabledBorders & Plasma::FrameSvg::TopBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerTopPix));
} else if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerLeftPix));
} else {
data[enabledBorders] << reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerPix));
}
#endif
int left, top, right, bottom = 0;
QSize marginHint;
if (enabledBorders & Plasma::FrameSvg::TopBorder) {
marginHint = q->elementSize(QStringLiteral("shadow-hint-top-margin"));
if (marginHint.isValid()) {
top = marginHint.height();
} else {
top = m_shadowPixmaps[0].height(); // top
}
} else {
top = 1;
}
if (enabledBorders & Plasma::FrameSvg::RightBorder) {
marginHint = q->elementSize(QStringLiteral("shadow-hint-right-margin"));
if (marginHint.isValid()) {
right = marginHint.width();
} else {
right = m_shadowPixmaps[2].width(); // right
}
} else {
right = 1;
}
if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
marginHint = q->elementSize(QStringLiteral("shadow-hint-bottom-margin"));
if (marginHint.isValid()) {
bottom = marginHint.height();
} else {
bottom = m_shadowPixmaps[4].height(); // bottom
}
} else {
bottom = 1;
}
if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
marginHint = q->elementSize(QStringLiteral("shadow-hint-left-margin"));
if (marginHint.isValid()) {
left = marginHint.width();
} else {
left = m_shadowPixmaps[6].width(); // left
}
} else {
left = 1;
}
data[enabledBorders] << top << right << bottom << left;
}
void PanelShadows::Private::freeX11Pixmaps()
{
#if HAVE_X11
if (!m_isX11) {
return;
}
auto *display = QX11Info::display();
if (!display) {
return;
}
foreach (const QPixmap &pixmap, m_shadowPixmaps) {
if (!pixmap.isNull()) {
XFreePixmap(display, reinterpret_cast<unsigned long>(createPixmap(pixmap)));
}
}
if (!m_emptyCornerPix.isNull()) {
XFreePixmap(display, reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerPix)));
}
if (!m_emptyCornerBottomPix.isNull()) {
XFreePixmap(display, reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerBottomPix)));
}
if (!m_emptyCornerLeftPix.isNull()) {
XFreePixmap(display, reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerLeftPix)));
}
if (!m_emptyCornerRightPix.isNull()) {
XFreePixmap(display, reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerRightPix)));
}
if (!m_emptyCornerTopPix.isNull()) {
XFreePixmap(display, reinterpret_cast<unsigned long>(createPixmap(m_emptyCornerTopPix)));
}
if (!m_emptyVerticalPix.isNull()) {
XFreePixmap(display, reinterpret_cast<unsigned long>(createPixmap(m_emptyVerticalPix)));
}
if (!m_emptyHorizontalPix.isNull()) {
XFreePixmap(display, reinterpret_cast<unsigned long>(createPixmap(m_emptyHorizontalPix)));
}
#endif
}
void PanelShadows::Private::clearPixmaps()
{
#if HAVE_X11
freeX11Pixmaps();
m_emptyCornerPix = QPixmap();
m_emptyCornerBottomPix = QPixmap();
m_emptyCornerLeftPix = QPixmap();
m_emptyCornerRightPix = QPixmap();
m_emptyCornerTopPix = QPixmap();
m_emptyVerticalPix = QPixmap();
m_emptyHorizontalPix = QPixmap();
#endif
freeWaylandBuffers();
m_shadowPixmaps.clear();
data.clear();
}
void PanelShadows::Private::freeWaylandBuffers()
{
m_wayland.shadowBuffers.clear();
}
void PanelShadows::Private::updateShadow(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
{
#if HAVE_X11
if (m_isX11) {
updateShadowX11(window, enabledBorders);
}
#endif
if (m_wayland.manager) {
updateShadowWayland(window, enabledBorders);
}
}
void PanelShadows::Private::updateShadowX11(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
{
#if HAVE_X11
if (m_shadowPixmaps.isEmpty()) {
setupPixmaps();
}
if (!data.contains(enabledBorders)) {
setupData(enabledBorders);
}
Display *dpy = QX11Info::display();
Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False);
qDebug() << "going to set the shadow of" << window->winId() << "to" << data;
XChangeProperty(dpy, window->winId(), atom, XA_CARDINAL, 32, PropModeReplace,
reinterpret_cast<const unsigned char *>(data[enabledBorders].constData()), data[enabledBorders].size());
#endif
}
void PanelShadows::Private::updateShadowWayland(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
{
if (!m_wayland.shmPool) {
return;
}
if (m_wayland.shadowBuffers.isEmpty()) {
setupPixmaps();
}
// TODO: check whether the surface already has a shadow
KWayland::Client::Surface *surface = KWayland::Client::Surface::fromWindow(const_cast<QWindow *>(window));
if (!surface) {
return;
}
auto shadow = m_wayland.manager->createShadow(surface, surface);
//shadow-top
if (enabledBorders & Plasma::FrameSvg::TopBorder) {
shadow->attachTop(m_wayland.shadowBuffers.at(0));
}
//shadow-topright
if (enabledBorders & Plasma::FrameSvg::TopBorder &&
enabledBorders & Plasma::FrameSvg::RightBorder) {
shadow->attachTopRight(m_wayland.shadowBuffers.at(1));
}
//shadow-right
if (enabledBorders & Plasma::FrameSvg::RightBorder) {
shadow->attachRight(m_wayland.shadowBuffers.at(2));
}
//shadow-bottomright
if (enabledBorders & Plasma::FrameSvg::BottomBorder &&
enabledBorders & Plasma::FrameSvg::RightBorder) {
shadow->attachBottomRight(m_wayland.shadowBuffers.at(3));
}
//shadow-bottom
if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
shadow->attachBottom(m_wayland.shadowBuffers.at(4));
}
//shadow-bottomleft
if (enabledBorders & Plasma::FrameSvg::BottomBorder &&
enabledBorders & Plasma::FrameSvg::LeftBorder) {
shadow->attachBottomLeft(m_wayland.shadowBuffers.at(5));
}
//shadow-left
if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
shadow->attachLeft(m_wayland.shadowBuffers.at(6));
}
//shadow-topleft
if (enabledBorders & Plasma::FrameSvg::TopBorder &&
enabledBorders & Plasma::FrameSvg::LeftBorder) {
shadow->attachTopLeft(m_wayland.shadowBuffers.at(7));
}
QSize marginHint;
QMarginsF margins = QMarginsF(1, 1, 1, 1);
if (enabledBorders & Plasma::FrameSvg::TopBorder) {
marginHint = q->elementSize(QStringLiteral("shadow-hint-top-margin"));
if (marginHint.isValid()) {
margins.setTop(marginHint.height());
} else {
margins.setTop(m_shadowPixmaps[0].height());
}
}
if (enabledBorders & Plasma::FrameSvg::RightBorder) {
marginHint = q->elementSize(QStringLiteral("shadow-hint-right-margin"));
if (marginHint.isValid()) {
margins.setRight(marginHint.width());
} else {
margins.setRight(m_shadowPixmaps[2].width());
}
}
if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
marginHint = q->elementSize(QStringLiteral("shadow-hint-bottom-margin"));
if (marginHint.isValid()) {
margins.setBottom(marginHint.height());
} else {
margins.setBottom(m_shadowPixmaps[4].height());
}
}
if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
marginHint = q->elementSize(QStringLiteral("shadow-hint-left-margin"));
if (marginHint.isValid()) {
margins.setLeft(marginHint.width());
} else {
margins.setLeft(m_shadowPixmaps[6].width());
}
}
shadow->setOffsets(margins);
shadow->commit();
surface->commit(KWayland::Client::Surface::CommitFlag::None);
}
void PanelShadows::Private::clearShadow(const QWindow *window)
{
if (!static_cast<const QSurface *>(window)->surfaceHandle()) {
qWarning() << "Cannot clear shadow from window without native surface!";
return;
}
#if HAVE_X11
if (m_isX11) {
clearShadowX11(window);
}
#endif
if (m_wayland.manager) {
clearShadowWayland(window);
}
}
void PanelShadows::Private::clearShadowX11(const QWindow *window)
{
#if HAVE_X11
Display *dpy = QX11Info::display();
Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False);
XDeleteProperty(dpy, window->winId(), atom);
#endif
}
void PanelShadows::Private::clearShadowWayland(const QWindow *window)
{
KWayland::Client::Surface *surface = KWayland::Client::Surface::fromWindow(const_cast<QWindow *>(window));
if (!surface) {
return;
}
m_wayland.manager->removeShadow(surface);
surface->commit(KWayland::Client::Surface::CommitFlag::None);
}
bool PanelShadows::enabled() const
{
return hasElement(QStringLiteral("shadow-left"));
}
void PanelShadows::Private::setupWaylandIntegration()
{
if (!KWindowSystem::isPlatformWayland()) {
return;
}
using namespace KWayland::Client;
ConnectionThread *connection = ConnectionThread::fromApplication(q);
if (!connection) {
return;
}
Registry *registry = new Registry(q);
registry->create(connection);
connect(registry, &Registry::shadowAnnounced, q,
[this, registry](quint32 name, quint32 version) {
m_wayland.manager = registry->createShadowManager(name, version, q);
updateShadows();
}, Qt::QueuedConnection
);
connect(registry, &Registry::shmAnnounced, q,
[this, registry](quint32 name, quint32 version) {
m_wayland.shmPool = registry->createShmPool(name, version, q);
updateShadows();
}, Qt::QueuedConnection
);
registry->setup();
connection->roundtrip();
}
#include "moc_panelshadows_p.cpp"

52
app/panelshadows_p.h Normal file
View File

@ -0,0 +1,52 @@
/*
* Copyright 2011 by Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PLASMA_PANELSHADOWS_H
#define PLASMA_PANELSHADOWS_H
#include <QSet>
#include "plasma/framesvg.h"
#include "plasma/svg.h"
class PanelShadows : public Plasma::Svg {
Q_OBJECT
public:
explicit PanelShadows(QObject *parent = 0, const QString &prefix = QStringLiteral("widgets/panel-background"));
~PanelShadows() override;
static PanelShadows *self();
void addWindow(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders = Plasma::FrameSvg::AllBorders);
void removeWindow(const QWindow *window);
void setEnabledBorders(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders = Plasma::FrameSvg::AllBorders);
bool enabled() const;
private:
class Private;
Private *const d;
Q_PRIVATE_SLOT(d, void updateShadows())
Q_PRIVATE_SLOT(d, void windowDestroyed(QObject *deletedObject))
};
#endif

View File

@ -305,5 +305,18 @@ Window{
text: visibilityManager.panelIsBiggerFromIconSize text: visibilityManager.panelIsBiggerFromIconSize
} }
Text{
text: "Draw Shadows (external)"+space
}
Text{
text: {
if (root.drawShadowsExternal)
return "Yes";
else
return "No";
}
}
} }
} }

View File

@ -27,8 +27,8 @@ import org.kde.latte 0.1 as Latte
Image{ Image{
id: editVisual id: editVisual
width: root.isHorizontal ? root.maxLength : visibilityManager.thicknessNormalOriginal width: root.isHorizontal ? editLength : visibilityManager.thicknessNormalOriginal
height: root.isVertical ? root.maxLength : visibilityManager.thicknessNormalOriginal height: root.isVertical ? editLength : visibilityManager.thicknessNormalOriginal
fillMode: Image.Tile fillMode: Image.Tile
source: "../icons/blueprint.jpg" source: "../icons/blueprint.jpg"
@ -37,6 +37,8 @@ Image{
property int speed: root.durationTime*4*units.longDuration property int speed: root.durationTime*4*units.longDuration
property int thickness: visibilityManager.thicknessNormalOriginal + root.editShadow property int thickness: visibilityManager.thicknessNormalOriginal + root.editShadow
property int rootThickness: visibilityManager.thicknessZoomOriginal + root.editShadow property int rootThickness: visibilityManager.thicknessZoomOriginal + root.editShadow
property int editLength: root.isHorizontal ? (root.drawShadowsExternal ? root.width - plasmoid.configuration.iconSize/4 : root.maxLength) :
(root.drawShadowsExternal ? root.height - plasmoid.configuration.iconSize/4 : root.maxLength)
property bool animationSent: false property bool animationSent: false
property bool farEdge: (plasmoid.location===PlasmaCore.Types.BottomEdge) || (plasmoid.location===PlasmaCore.Types.RightEdge) property bool farEdge: (plasmoid.location===PlasmaCore.Types.BottomEdge) || (plasmoid.location===PlasmaCore.Types.RightEdge)
@ -49,7 +51,6 @@ Image{
color: "#ee080808" color: "#ee080808"
} }
/*Behavior on width { /*Behavior on width {
NumberAnimation { duration: 300 } NumberAnimation { duration: 300 }
enabled: root.isHorizontal enabled: root.isHorizontal
@ -76,7 +77,7 @@ Image{
} }
onEditAnimationEndedChanged: { onEditAnimationEndedChanged: {
if (editAnimationEnded) { if (editAnimationEnded && !root.drawShadowsExternal) {
dock.shadow = root.editShadow; dock.shadow = root.editShadow;
} else { } else {
dock.shadow = 0; dock.shadow = 0;
@ -108,23 +109,23 @@ Image{
if (root.isHorizontal) { if (root.isHorizontal) {
if (plasmoid.configuration.panelPosition === Latte.Dock.Justify) { if (plasmoid.configuration.panelPosition === Latte.Dock.Justify) {
x = root.width/2 - root.maxLength/2; x = root.width/2 - editVisual.editLength/2;
} else if (root.panelAlignment === Latte.Dock.Left) { } else if (root.panelAlignment === Latte.Dock.Left) {
x = 0; x = 0;
} else if (root.panelAlignment === Latte.Dock.Center) { } else if (root.panelAlignment === Latte.Dock.Center) {
x = root.width/2 - root.maxLength/2; x = root.width/2 - editVisual.editLength/2;
} else if (root.panelAlignment === Latte.Dock.Right) { } else if (root.panelAlignment === Latte.Dock.Right) {
x = root.width - root.maxLength; x = root.width - editVisual.editLength;
} }
} else if (root.isVertical) { } else if (root.isVertical) {
if (plasmoid.configuration.panelPosition === Latte.Dock.Justify) { if (plasmoid.configuration.panelPosition === Latte.Dock.Justify) {
y = root.height/2 - root.maxLength/2; y = root.height/2 - editVisual.editLength/2;
} else if (root.panelAlignment === Latte.Dock.Top) { } else if (root.panelAlignment === Latte.Dock.Top) {
y = 0; y = 0;
} else if (root.panelAlignment === Latte.Dock.Center) { } else if (root.panelAlignment === Latte.Dock.Center) {
y = root.height/2 - root.maxLength/2; y = root.height/2 - editVisual.editLength/2;
} else if (root.panelAlignment === Latte.Dock.Bottom) { } else if (root.panelAlignment === Latte.Dock.Bottom) {
y = root.height - root.maxLength; y = root.height - editVisual.editLength;
} }
} }
} }
@ -204,7 +205,7 @@ Image{
PropertyAnimation { PropertyAnimation {
target: editVisual target: editVisual
property: "opacity" property: "opacity"
to: 0.6 to: root.drawShadowsExternal ? 0.3 : 0.6
duration: editVisual.speed / 2 duration: editVisual.speed / 2
easing.type: Easing.OutQuad easing.type: Easing.OutQuad
} }

View File

@ -35,11 +35,12 @@ Item{
opacity: root.useThemePanel ? 1 : 0 opacity: root.useThemePanel ? 1 : 0
// parent: root // parent: root
z:0
property int panelWidth: (root.panelAlignment === Latte.Dock.Justify) && root.isHorizontal && !root.editMode ? property int panelWidth: root.drawShadowsExternal ? root.width :
(root.panelAlignment === Latte.Dock.Justify) && root.isHorizontal && !root.editMode ?
layoutsContainer.width + spacing : mainLayout.width + spacing layoutsContainer.width + spacing : mainLayout.width + spacing
property int panelHeight: (root.panelAlignment === Latte.Dock.Justify) && root.isVertical && !root.editMode ? property int panelHeight: root.drawShadowsExternal ? root.height :
(root.panelAlignment === Latte.Dock.Justify) && root.isVertical && !root.editMode ?
layoutsContainer.height + spacing : mainLayout.height + spacing layoutsContainer.height + spacing : mainLayout.height + spacing
width: root.isHorizontal ? panelWidth : smallSize width: root.isHorizontal ? panelWidth : smallSize
@ -86,21 +87,40 @@ Item{
PlasmaCore.FrameSvgItem{ PlasmaCore.FrameSvgItem{
id: shadowsSvgItem id: shadowsSvgItem
width: root.isVertical ? panelSize + margins.left + margins.right: parent.width + margins.left + margins.right width: root.isVertical ? panelSize + marginsWidth: parent.width + marginsWidth
height: root.isVertical ? parent.height + margins.left + margins.right : panelSize + margins.top + margins.bottom height: root.isVertical ? parent.height + marginsHeight : panelSize + marginsHeight
imagePath: "translucent/widgets/panel-background" imagePath: root.drawShadowsExternal ? "" : "translucent/widgets/panel-background"
prefix:"shadow" prefix: root.drawShadowsExternal ? "" : "shadow"
opacity: root.useThemePanel ? 1 : 0 opacity: root.useThemePanel ? 1 : 0
visible: (opacity == 0) ? false : true visible: (opacity == 0) ? false : true
property int marginsWidth: root.drawShadowsExternal ? 0 : margins.left + margins.right
property int marginsHeight: root.drawShadowsExternal ? 0 : margins.top + margins.bottom
property int panelSize: automaticPanelSize property int panelSize: automaticPanelSize
property int automaticPanelSize: root.drawShadowsExternal ? root.themePanelSize + root.panelShadow:
Math.min(root.themePanelSize + root.panelShadow + 1,
root.statesLineSize + root.iconSize + root.iconMargin + 1)
property int automaticPanelSize: Math.min(root.themePanelSize + root.panelShadow, root.statesLineSize + root.iconSize + root.iconMargin) property int shadowsSize: {
if (shadowsSvgItem && root.useThemePanel){
property int shadowsSize: shadowsSvgItem && root.useThemePanel ? if (root.isVertical){
(root.isVertical ? shadowsSvgItem.margins.right : shadowsSvgItem.margins.bottom) : 0 if (plasmoid.location === PlasmaCore.Types.LeftEdge)
return shadowsSvgItem.margins.right;
else if (plasmoid.location === PlasmaCore.Types.RightEdge)
return shadowsSvgItem.margins.left;
} else {
if (plasmoid.location === PlasmaCore.Types.BottomEdge)
return shadowsSvgItem.margins.top;
else if (plasmoid.location === PlasmaCore.Types.TopEdge)
return shadowsSvgItem.margins.bottom;
}
} else {
return 0;
}
}
Behavior on opacity{ Behavior on opacity{
NumberAnimation { duration: 200 } NumberAnimation { duration: 200 }
@ -122,11 +142,47 @@ Item{
PlasmaCore.FrameSvgItem{ PlasmaCore.FrameSvgItem{
anchors.margins: belower.width-1 anchors.margins: root.drawShadowsExternal ? 0 : belower.width-1
anchors.fill:parent anchors.fill:parent
// imagePath: root.transparentPanel ? "translucent/widgets/panel-background" : // imagePath: root.transparentPanel ? "translucent/widgets/panel-background" :
// "widgets/panel-background" // "widgets/panel-background"
imagePath: "widgets/panel-background" imagePath: "widgets/panel-background"
onRepaintNeeded: {
if (root.drawShadowsExternal)
adjustPrefix();
}
enabledBorders: dock.enabledBorders
function adjustPrefix() {
if (!plasmoid) {
return "";
}
var pre;
switch (plasmoid.location) {
case PlasmaCore.Types.LeftEdge:
pre = "west";
break;
case PlasmaCore.Types.TopEdge:
pre = "north";
break;
case PlasmaCore.Types.RightEdge:
pre = "east";
break;
case PlasmaCore.Types.BottomEdge:
pre = "south";
break;
default:
prefix = "";
}
if (hasElementPrefix(pre)) {
prefix = pre;
} else {
prefix = "";
}
}
} }
} }

View File

@ -40,7 +40,7 @@ Item{
property bool inStartup: root.inStartup property bool inStartup: root.inStartup
property bool normalState : false // this is being set from updateMaskArea property bool normalState : false // this is being set from updateMaskArea
property bool previousNormalState : false // this is only for debugging purposes property bool previousNormalState : false // this is only for debugging purposes
property bool panelIsBiggerFromIconSize: root.realPanelSize+root.panelShadow > root.statesLineSize + root.iconSize + root.iconMargin + 1 property bool panelIsBiggerFromIconSize: root.useThemePanel && (root.themePanelSize >= (root.iconSize + root.iconMargin + 1))
property int animationSpeed: root.durationTime * 1.2 * units.longDuration property int animationSpeed: root.durationTime * 1.2 * units.longDuration
property int length: root.isVertical ? Screen.height : Screen.width //screenGeometry.height : screenGeometry.width property int length: root.isVertical ? Screen.height : Screen.width //screenGeometry.height : screenGeometry.width
@ -75,6 +75,20 @@ Item{
value: thicknessNormalOriginal value: thicknessNormalOriginal
} }
Binding{
target: dock
property: "drawShadows"
when: dock
value: root.drawShadowsExternal
}
Binding{
target: dock
property: "maxLength"
when: dock
value: plasmoid.configuration.maxLength/100
}
onInStartupChanged: { onInStartupChanged: {
if (!inStartup) { if (!inStartup) {
delayAnimationTimer.start(); delayAnimationTimer.start();
@ -263,7 +277,11 @@ Item{
newMaskArea.height = tempLength; newMaskArea.height = tempLength;
} }
if (root.drawShadowsExternal) {
dock.maskArea = Qt.rect(0,0,root.width,root.height);
} else {
dock.maskArea = newMaskArea; dock.maskArea = newMaskArea;
}
//console.log("update mask area:"+newMaskArea); //console.log("update mask area:"+newMaskArea);
if(normalState && !dock.visibility.isHidden){ if(normalState && !dock.visibility.isHidden){
@ -271,7 +289,7 @@ Item{
//the shadows size must be removed from the maskArea //the shadows size must be removed from the maskArea
//before updating the localDockGeometry //before updating the localDockGeometry
if(panelIsBiggerFromIconSize) { if(panelIsBiggerFromIconSize && !root.drawShadowsExternal) {
var shadow = root.panelShadow; var shadow = root.panelShadow;
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) { if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {

View File

@ -46,6 +46,10 @@ DragDrop.DropArea {
property bool automaticSize: plasmoid.configuration.automaticIconSize property bool automaticSize: plasmoid.configuration.automaticIconSize
property bool confirmedDragEntered: false property bool confirmedDragEntered: false
property bool drawShadowsExternal: visibilityManager.panelIsBiggerFromIconSize && (zoomFactor === 1.0)
&& (dock.visibility.mode === Latte.Dock.AlwaysVisible)
&& (plasmoid.configuration.panelPosition === Latte.Dock.Justify)
property bool editMode: plasmoid.userConfiguring property bool editMode: plasmoid.userConfiguring
property bool immutable: plasmoid.immutable property bool immutable: plasmoid.immutable
property bool inStartup: true property bool inStartup: true
@ -1040,6 +1044,19 @@ DragDrop.DropArea {
EditModeVisual{ EditModeVisual{
id:editModeVisual id:editModeVisual
z: root.drawShadowsExternal ? 1 : 0
}
Loader{
anchors.fill: layoutsContainer
// FIX IT && TEST IT: it is crashing Plasma with two Now Docks one of which has only
// task manager (small)
//active: root.useThemePanel
active: windowSystem.compositingActive
sourceComponent: PanelBox{}
z: root.drawShadowsExternal ? 0 : 1
} }
Item { Item {
@ -1048,6 +1065,7 @@ DragDrop.DropArea {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
z:10
Rectangle{ Rectangle{
anchors.fill: parent anchors.fill: parent
@ -1069,6 +1087,7 @@ DragDrop.DropArea {
Layout.preferredWidth: width Layout.preferredWidth: width
Layout.preferredHeight: height Layout.preferredHeight: height
opacity: 0 opacity: 0
z:10
AddWidgetVisual{} AddWidgetVisual{}
} }
@ -1076,6 +1095,7 @@ DragDrop.DropArea {
Loader{ Loader{
anchors.fill: parent anchors.fill: parent
active: root.debugMode active: root.debugMode
z:10
sourceComponent: Item{ sourceComponent: Item{
Rectangle{ Rectangle{
@ -1100,15 +1120,16 @@ DragDrop.DropArea {
property int hoveredIndex: -1 property int hoveredIndex: -1
x: (plasmoid.configuration.panelPosition === Latte.Dock.Justify) && root.isHorizontal x: (plasmoid.configuration.panelPosition === Latte.Dock.Justify) && root.isHorizontal
&& !root.editMode && windowSystem.compositingActive ? && !root.editMode && windowSystem.compositingActive && !root.drawShadowsExternal ?
(dock.width/2) - (root.maxLength/2): 0 (dock.width/2) - (root.maxLength/2): 0
y: (plasmoid.configuration.panelPosition === Latte.Dock.Justify) && root.isVertical y: (plasmoid.configuration.panelPosition === Latte.Dock.Justify) && root.isVertical
&& !root.editMode && windowSystem.compositingActive ? && !root.editMode && windowSystem.compositingActive && !root.drawShadowsExternal ?
(dock.height/2) - (root.maxLength/2): 0 (dock.height/2) - (root.maxLength/2): 0
width: (plasmoid.configuration.panelPosition === Latte.Dock.Justify) && root.isHorizontal && !root.editMode ? width: (plasmoid.configuration.panelPosition === Latte.Dock.Justify) && root.isHorizontal && !root.editMode && !root.drawShadowsExternal ?
root.maxLength : parent.width root.maxLength : parent.width
height: (plasmoid.configuration.panelPosition === Latte.Dock.Justify) && root.isVertical && !root.editMode ? height: (plasmoid.configuration.panelPosition === Latte.Dock.Justify) && root.isVertical && !root.editMode && !root.drawShadowsExternal ?
root.maxLength : parent.height root.maxLength : parent.height
z:10
property bool shouldCheckHalfs: (plasmoid.configuration.panelPosition === Latte.Dock.Justify) && (mainLayout.children>1) property bool shouldCheckHalfs: (plasmoid.configuration.panelPosition === Latte.Dock.Justify) && (mainLayout.children>1)
@ -1147,20 +1168,6 @@ DragDrop.DropArea {
} }
} }
Loader{
anchors.fill: parent
// FIX IT && TEST IT: it is crashing Plasma with two Now Docks one of which has only
// task manager (small)
//active: root.useThemePanel
active: windowSystem.compositingActive
sourceComponent: PanelBox{}
}
Grid{ Grid{
id:startLayout id:startLayout

View File

@ -250,7 +250,7 @@ PlasmaComponents.Page {
value: plasmoid.configuration.panelSize value: plasmoid.configuration.panelSize
minimumValue: 0 minimumValue: 0
maximumValue: Number(1.12 * plasmoid.configuration.iconSize).toFixed(0) //0.12*iconSize is the iconMargin maximumValue: Number(1.2 * plasmoid.configuration.iconSize).toFixed(0) //0.12*iconSize is the iconMargin, 0.08 for statesLine
stepSize: 2 stepSize: 2
function updatePanelSize() { function updatePanelSize() {