Improve roundedwindow

pull/10/head
reionwong 4 years ago
parent 2360dd4904
commit 9b49cca2a5

1
debian/control vendored

@ -12,6 +12,7 @@ Build-Depends: cmake,
libkdecorations2-dev,
libkf5coreaddons-dev,
libqt5opengl5-dev,
libqt5x11extras5-dev,
qtbase5-dev,
qtbase5-private-dev,
qtdeclarative5-dev,

@ -5,10 +5,11 @@ find_package(KF5CoreAddons REQUIRED)
find_package(KF5Config REQUIRED)
find_package(KF5WindowSystem REQUIRED)
find_package(KDecoration2 REQUIRED)
find_package(Qt5 CONFIG REQUIRED COMPONENTS Gui Core)
find_package(Qt5 CONFIG REQUIRED COMPONENTS Gui Core X11Extras)
set (decoration_SRCS
decoration.cpp
x11shadow.cpp
button.cpp
resources.qrc
)
@ -21,6 +22,7 @@ target_link_libraries (cutefishdecoration
PUBLIC
Qt5::Core
Qt5::Gui
Qt5::X11Extras
KF5::ConfigCore
KF5::ConfigGui
KF5::CoreAddons

@ -52,10 +52,11 @@ static QColor g_shadowColor = Qt::black;
static QSharedPointer<KDecoration2::DecorationShadow> g_sShadow;
Decoration::Decoration(QObject *parent, const QVariantList &args)
: KDecoration2::Decoration(parent, args),
m_settings(new QSettings(QSettings::UserScope, "cutefishos", "theme")),
m_settingsFile(m_settings->fileName()),
m_fileWatcher(new QFileSystemWatcher)
: KDecoration2::Decoration(parent, args)
, m_settings(new QSettings(QSettings::UserScope, "cutefishos", "theme"))
, m_settingsFile(m_settings->fileName())
, m_fileWatcher(new QFileSystemWatcher)
, m_x11Shadow(new X11Shadow)
{
++g_sDecoCount;
}
@ -95,7 +96,6 @@ void Decoration::paint(QPainter *painter, const QRect &repaintRegion)
m_rightButtons->paint(painter, repaintRegion);
}
// paintTitleBarBackground(painter, repaintRegion);
paintCaption(painter, repaintRegion);
paintButtons(painter, repaintRegion);
}
@ -366,7 +366,8 @@ bool Decoration::darkMode() const
bool Decoration::radiusAvailable() const
{
return client().toStrongRef().data()->adjacentScreenEdges() == Qt::Edges();
return !isMaximized();
// return client().toStrongRef().data()->adjacentScreenEdges() == Qt::Edges();
}
bool Decoration::isMaximized() const
@ -408,20 +409,6 @@ QColor Decoration::titleBarForegroundColor() const
return color;
}
void Decoration::paintTitleBarBackground(QPainter *painter, const QRect &repaintRegion) const
{
Q_UNUSED(repaintRegion)
const auto *decoratedClient = client().toStrongRef().data();
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::red);
painter->drawRoundedRect(QRect(0, 0, decoratedClient->width(), titleBarHeight()), 6, 6);
painter->restore();
}
void Decoration::paintCaption(QPainter *painter, const QRect &repaintRegion) const
{
Q_UNUSED(repaintRegion)

@ -28,6 +28,8 @@
#include <QVariant>
#include <QIcon>
#include "x11shadow.h"
namespace Cutefish
{
@ -78,7 +80,6 @@ private:
bool isMaximized() const;
void paintFrameBackground(QPainter *painter, const QRect &repaintRegion) const;
void paintTitleBarBackground(QPainter *painter, const QRect &repaintRegion) const;
void paintCaption(QPainter *painter, const QRect &repaintRegion) const;
void paintButtons(QPainter *painter, const QRect &repaintRegion) const;
@ -109,6 +110,8 @@ private:
QPixmap m_maximizeBtnPixmap;
QPixmap m_minimizeBtnPixmap;
QPixmap m_restoreBtnPixmap;
X11Shadow *m_x11Shadow;
};
}

@ -0,0 +1,31 @@
#include "x11shadow.h"
#include <QX11Info>
#include <xcb/xcb.h>
static xcb_atom_t internAtom(const char *name, bool only_if_exists)
{
if (!name || *name == 0)
return XCB_NONE;
if (!QX11Info::isPlatformX11())
return XCB_NONE;
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(QX11Info::connection(), only_if_exists, strlen(name), name);
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(QX11Info::connection(), cookie, 0);
if (!reply)
return XCB_NONE;
xcb_atom_t atom = reply->atom;
free(reply);
return atom;
}
X11Shadow::X11Shadow(QObject *parent)
: QObject(parent)
{
m_atom_net_wm_shadow = internAtom("_KDE_NET_WM_SHADOW", false);
m_atom_net_wm_window_type = internAtom("_NET_WM_WINDOW_TYPE", false);
}

@ -0,0 +1,18 @@
#ifndef X11SHADOW_H
#define X11SHADOW_H
#include <QObject>
class X11Shadow : public QObject
{
Q_OBJECT
public:
explicit X11Shadow(QObject *parent = nullptr);
private:
quint32 m_atom_net_wm_shadow;
quint32 m_atom_net_wm_window_type;
};
#endif // X11SHADOW_H

@ -32,6 +32,22 @@ Q_DECLARE_METATYPE(QPainterPath)
typedef void (* SetDepth)(void *, int);
static SetDepth setDepthfunc = nullptr;
static QStringList allowList = { "netease-cloud-music netease-cloud-music",
"com.alibabainc.dingtalk com.alibabainc.dingtalk",
"tenvideo_universal tenvideo_universal",
"com.eusoft.ting.en com.eusoft.ting.en",
"i4toolslinux i4tools",
"youku-app youku-app",
"qqmusic qqmusic",
"mytime mytime",
"feishu feishu",
"xmind xmind",
"mtxx mtxx",
// Open source software
"code code"
};
// From ubreffect
static KWin::GLShader *getShader()
{
@ -170,11 +186,28 @@ static KWin::GLTexture *getTexture(int borderRadius)
RoundedWindow::RoundedWindow(QObject *, const QVariantList &)
: KWin::Effect()
, m_frameRadius(12)
, m_corner(m_frameRadius, m_frameRadius)
{
{
setDepthfunc = (SetDepth) QLibrary::resolve("kwin.so." + qApp->applicationVersion(), "_ZN4KWin8Toplevel8setDepthEi");
m_newShader = getShader();
QString name = "_NET_WM_STATE";
xcb_intern_atom_cookie_t cookie = xcb_intern_atom_unchecked(KWin::connection(), false, name.length(), name.toUtf8());
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(KWin::connection(), cookie, nullptr);
m_netWMStateAtom = reply->atom;
free(reply);
name = "_NET_WM_STATE_MAXIMIZED_HORZ";
cookie = xcb_intern_atom_unchecked(KWin::connection(), false, name.length(), name.toUtf8());
reply = xcb_intern_atom_reply(KWin::connection(), cookie, nullptr);
m_netWMStateMaxHorzAtom = reply->atom;
free(reply);
name = "_NET_WM_STATE_MAXIMIZED_VERT";
cookie = xcb_intern_atom_unchecked(KWin::connection(), false, name.length(), name.toUtf8());
reply = xcb_intern_atom_reply(KWin::connection(), cookie, nullptr);
m_netWMStateMaxVertAtom = reply->atom;
free(reply);
m_shader = getShader();
m_texure = getTexture(m_frameRadius);
}
@ -201,14 +234,34 @@ bool RoundedWindow::hasShadow(KWin::WindowQuadList &qds)
return false;
}
bool RoundedWindow::isMaximized(KWin::EffectWindow *w)
{
if (m_netWMStateAtom == 0)
return false;
QByteArray rawAtomData = w->readProperty(m_netWMStateAtom, XCB_ATOM_ATOM, 32);
if (!rawAtomData.isEmpty()) {
for (int i = 0; i < rawAtomData.length(); i += sizeof(xcb_atom_t)) {
xcb_atom_t atom = static_cast<xcb_atom_t>(rawAtomData.data()[i]) + 512;
if (atom == m_netWMStateMaxHorzAtom || atom == m_netWMStateMaxVertAtom)
return true;
}
}
return false;
}
void RoundedWindow::drawWindow(KWin::EffectWindow *w, int mask, const QRegion &region, KWin::WindowPaintData &data)
{
if (!w->isPaintingEnabled() || ((mask & PAINT_WINDOW_LANCZOS))) {
return KWin::Effect::drawWindow(w, mask, region, data);
}
if (!m_newShader->isValid()
|| KWin::effects->hasActiveFullScreenEffect()
if (isMaximized(w)) {
return KWin::Effect::drawWindow(w, mask, region, data);
}
if (KWin::effects->hasActiveFullScreenEffect()
|| w->isDesktop()
|| w->isMenu()
|| w->isDock()
@ -216,7 +269,8 @@ void RoundedWindow::drawWindow(KWin::EffectWindow *w, int mask, const QRegion &r
|| w->isPopupMenu()
|| w->isFullScreen()
|| !hasShadow(data.quads)) {
return KWin::Effect::drawWindow(w, mask, region, data);
if (!allowList.contains(w->windowClass()))
return KWin::Effect::drawWindow(w, mask, region, data);
}
// 设置 alpha 通道混合
@ -226,8 +280,6 @@ void RoundedWindow::drawWindow(KWin::EffectWindow *w, int mask, const QRegion &r
}
}
KWin::WindowPaintData paintData = data;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -257,28 +309,31 @@ void RoundedWindow::drawWindow(KWin::EffectWindow *w, int mask, const QRegion &r
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glActiveTexture(GL_TEXTURE0);
paintData.shader = m_newShader;
KWin::ShaderManager::instance()->pushShader(m_newShader);
KWin::GLShader *oldShader = data.shader;
data.shader = m_shader;
KWin::ShaderManager::instance()->pushShader(m_shader);
m_newShader->setUniform("topleft", 10);
m_newShader->setUniform("scale", QVector2D(w->width() * 1.0 / textureTopLeft->width(),
m_shader->setUniform("topleft", 10);
m_shader->setUniform("scale", QVector2D(w->width() * 1.0 / textureTopLeft->width(),
w->height() * 1.0 / textureTopLeft->height()));
m_newShader->setUniform("topright", 11);
m_newShader->setUniform("scale1", QVector2D(w->width() * 1.0 / textureTopRight->width(),
m_shader->setUniform("topright", 11);
m_shader->setUniform("scale1", QVector2D(w->width() * 1.0 / textureTopRight->width(),
w->height() * 1.0 / textureTopRight->height()));
m_newShader->setUniform("bottomleft", 12);
m_newShader->setUniform("scale2", QVector2D(w->width() * 1.0 / textureBottomLeft->width(),
m_shader->setUniform("bottomleft", 12);
m_shader->setUniform("scale2", QVector2D(w->width() * 1.0 / textureBottomLeft->width(),
w->height() * 1.0 / textureBottomLeft->height()));
m_newShader->setUniform("bottomright", 13);
m_newShader->setUniform("scale3", QVector2D(w->width() * 1.0 / textureBottomRight->width(),
m_shader->setUniform("bottomright", 13);
m_shader->setUniform("scale3", QVector2D(w->width() * 1.0 / textureBottomRight->width(),
w->height() * 1.0 / textureBottomRight->height()));
KWin::Effect::drawWindow(w, mask, region, paintData);
KWin::Effect::drawWindow(w, mask, region, data);
KWin::ShaderManager::instance()->popShader();
data.shader = oldShader;
glActiveTexture(GL_TEXTURE10);
textureTopLeft->unbind();
glActiveTexture(GL_TEXTURE0);

@ -25,6 +25,8 @@
#include <kwinglplatform.h>
#include <kwinglutils.h>
#include <xcb/xcb_atom.h>
class RoundedWindow : public KWin::Effect
{
Q_OBJECT
@ -43,16 +45,21 @@ public:
static bool supported();
static bool enabledByDefault();
bool hasShadow(KWin::WindowQuadList &qds);
bool isMaximized(KWin::EffectWindow *w);
void drawWindow(KWin::EffectWindow* w, int mask, const QRegion &region, KWin::WindowPaintData& data) override;
private:
KWin::GLShader *m_newShader;
KWin::GLShader *m_shader;
KWin::GLTexture *m_texure;
xcb_atom_t m_netWMStateAtom = 0;
xcb_atom_t m_netWMStateMaxHorzAtom = 0;
xcb_atom_t m_netWMStateMaxVertAtom = 0;
int m_frameRadius;
QSize m_corner;
};
#endif

Loading…
Cancel
Save