Skip to content

Commit

Permalink
Merge pull request #82 from matinlotfali/draw-shadows
Browse files Browse the repository at this point in the history
  • Loading branch information
matinlotfali authored Jun 18, 2023
2 parents 3d815fc + 7bc2c2e commit 923f705
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 114 deletions.
12 changes: 12 additions & 0 deletions ConfigModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@

const QString
key_size = "roundness",
key_shadowSize = "shadowSize",
key_inactiveShadowSize = "inactiveShadowSize",
key_shadowColor = "shadowColor",
key_inactiveShadowColor = "inactiveShadowColor",
key_outlineColor = "outlineColor",
key_inactiveOutlineColor = "inactiveOutlineColor",
key_outlineThickness = "outlineThickness";

ConfigModel::ConfigModel():
m_size(10),
m_shadowSize(25),
m_inactiveShadowSize(20),
m_outlineThickness(1),
m_shadowColor(QColor(Qt::black)),
m_inactiveShadowColor(QColor(Qt::black)),
m_outlineColor(QColor(Qt::black)),
m_inactiveOutlineColor(QColor(Qt::black))
{
Expand All @@ -25,7 +31,10 @@ ConfigModel::ConfigModel():
void ConfigModel::Load() {
KConfigGroup conf = KSharedConfig::openConfig("shapecorners.conf")->group("General");
m_size = conf.readEntry(key_size, m_size);
m_shadowSize = conf.readEntry(key_shadowSize, m_shadowSize);
m_inactiveShadowSize = conf.readEntry(key_inactiveShadowSize, m_inactiveShadowSize);
m_shadowColor = conf.readEntry(key_shadowColor, m_shadowColor);
m_inactiveShadowColor = conf.readEntry(key_inactiveShadowColor, m_inactiveShadowColor);
m_outlineColor = conf.readEntry(key_outlineColor, m_outlineColor);
m_inactiveOutlineColor = conf.readEntry(key_inactiveOutlineColor,m_inactiveOutlineColor);
m_outlineThickness = conf.readEntry(key_outlineThickness, m_outlineThickness);
Expand All @@ -34,7 +43,10 @@ void ConfigModel::Load() {
void ConfigModel::Save() const {
KConfigGroup conf = KSharedConfig::openConfig("shapecorners.conf")->group("General");
conf.writeEntry(key_size, m_size);
conf.writeEntry(key_shadowSize, m_shadowSize);
conf.writeEntry(key_inactiveShadowSize, m_inactiveShadowSize);
conf.writeEntry(key_shadowColor, m_shadowColor);
conf.writeEntry(key_inactiveShadowColor, m_inactiveShadowColor);
conf.writeEntry(key_outlineColor, m_outlineColor);
conf.writeEntry(key_inactiveOutlineColor,m_inactiveOutlineColor);
conf.writeEntry(key_outlineThickness, m_outlineThickness);
Expand Down
3 changes: 3 additions & 0 deletions ConfigModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ class ConfigModel {
void Save() const;

float m_size,
m_shadowSize,
m_inactiveShadowSize,
m_outlineThickness;
QColor m_shadowColor,
m_inactiveShadowColor,
m_outlineColor,
m_inactiveOutlineColor;
};
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This effect rounds the corners of your windows and adds an outline around them without much affecting the performance of the KDE Plasma desktop (see [#49](https://github.com/matinlotfali/KDE-Rounded-Corners/pull/49) and [#50](https://github.com/matinlotfali/KDE-Rounded-Corners/issues/50)).

This effect started as a fork of [shapecorners](https://sourceforge.net/projects/shapecorners/) with some additional contributions in [Alex47's project](https://github.com/alex47/KDE-Rounded-Corners), then I optimized and reimplemented the effect with shaders.
This effect started as a fork of [shapecorners](https://sourceforge.net/projects/shapecorners/) with some additional contributions in [Alex47's project](https://github.com/alex47/KDE-Rounded-Corners), then I optimized and reimplemented the effect with shaders with influences from the [invert effect](https://github.com/KDE/kwin/tree/master/src/plugins/invert).

#### Tested on:
- ![Kubuntu 22.04 Jammy](https://img.shields.io/badge/-not_supported-red?label=Kubuntu%2022.04%20Jammy&logo=kubuntu&branch=master)
Expand All @@ -17,7 +17,7 @@ This effect started as a fork of [shapecorners](https://sourceforge.net/projects
![](https://img.shields.io/badge/KWinEffects-v237-lightgrey)
- [![Arch](https://img.shields.io/github/actions/workflow/status/matinlotfali/KDE-Rounded-Corners/arch.yml?branch=master&label=Arch%20Linux&logo=archlinux&logoColor=white) ![](https://img.shields.io/aur/maintainer/kwin-effect-rounded-corners-git?label=AUR%20Maintainer) ![](https://img.shields.io/aur/votes/kwin-effect-rounded-corners-git?label=AUR%20Votes)](https://aur.archlinux.org/packages/kwin-effect-rounded-corners-git)

![After](https://raw.githubusercontent.com/matinlotfali/KDE-Rounded-Corners/master/screenshots/outlines.png)
![After](screenshots/shadows.png)

# Contributions:

Expand Down
Binary file added screenshots/shadows.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
79 changes: 32 additions & 47 deletions shaders_110/shapecorners.frag
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,33 @@

uniform sampler2D front;
uniform float radius;
uniform bool windowActive;
uniform bool windowHasDecoration;
uniform vec2 windowSize;
uniform vec2 windowExpandedSize;
uniform vec2 windowTopLeft;
uniform vec4 shadowColor;
uniform float shadowSize;
uniform vec4 outlineColor;
uniform float outlineThickness;
uniform vec4 modulation;
uniform float saturation;

varying vec2 texcoord0;

bool isDrawingShadows() { return windowHasDecoration && shadowColor.a > 0.0; }
bool isDrawingOutline() { return outlineColor.a > 0.0 && outlineThickness > 0.0; }
bool isExtendedFrame(vec2 c) {
return c.x < -1.0 || c.x > windowSize.x+1.0
|| c.y < -1.0 || c.y > windowSize.y+1.0;
}

vec4 shadowCorner(float distance_from_center, bool isTopCorner) {
float r2 = radius * sqrt(2.0);
float percent;
if (windowActive) {
if (isTopCorner)
percent = (distance_from_center) / (r2 + 0.1*radius);
else
percent = (distance_from_center - 0.25*radius) / (r2 + 0.1*radius);
}
else {
if (isTopCorner)
percent = (distance_from_center + 0.55*radius) / (r2 + 0.5*radius);
else
percent = (distance_from_center) / (r2 + 0.1*radius);
}
return vec4(shadowColor.rgb, 1.0-percent);
vec4 shadowCorner(float distance_from_center) {
float percent = -distance_from_center/shadowSize + 1.0;
if (percent < 0.0)
return vec4(0.0, 0.0, 0.0, 0.0);
else
return vec4(shadowColor.rgb, percent);
}

vec4 shapeCorner(vec2 coord0, vec4 tex, vec2 center, bool isTopCorner) {
vec4 shapeCorner(vec2 coord0, vec4 tex, vec2 center) {
float distance_from_center = distance(coord0, center);
vec4 c = isDrawingShadows() ? shadowCorner(distance_from_center, isTopCorner) : vec4(0.0,0.0,0.0,0.0);
vec4 c = isDrawingShadows() ? shadowCorner(distance_from_center) : vec4(0.0,0.0,0.0,0.0);

if(isDrawingOutline()) {
vec4 outlineOverlay = vec4(mix(tex.rgb, outlineColor.rgb, outlineColor.a), 1.0);
Expand All @@ -66,30 +54,27 @@ void main(void)
vec2 coord0 = vec2(texcoord0.x * windowExpandedSize.x - windowTopLeft.x,
(1.0-texcoord0.y)* windowExpandedSize.y - windowTopLeft.y);

if(!isExtendedFrame(coord0))
{
if (coord0.y < radius - 1.0) {
if (coord0.x < radius - 1.0)
tex = shapeCorner(coord0, tex, vec2(radius-1.0, radius-1.0), true);
else if (coord0.x > windowSize.x - radius + 1.0)
tex = shapeCorner(coord0, tex, vec2(windowSize.x - radius+1.0, radius-1.0), true);
else if (coord0.y < outlineThickness - 1.0)
tex.rgb = mix(tex.rgb, outlineColor.rgb, outlineColor.a);
}
else if (coord0.y > windowSize.y - radius) {
if (coord0.x < radius - 1.0)
tex = shapeCorner(coord0, tex, vec2(radius-1.0, windowSize.y - radius+1.0), false);
else if (coord0.x > windowSize.x - radius + 1.0)
tex = shapeCorner(coord0, tex, vec2(windowSize.x - radius+1.0, windowSize.y - radius+1.0), false);
else if (coord0.y > windowSize.y - outlineThickness + 1.0)
tex.rgb = mix(tex.rgb, outlineColor.rgb, outlineColor.a);
}
else {
if (outlineColor.a > 0.0 && coord0.x < outlineThickness - 1.0)
tex.rgb = mix(tex.rgb, outlineColor.rgb, outlineColor.a);
else if (outlineColor.a > 0.0 && coord0.x > windowSize.x - outlineThickness + 1.0)
tex.rgb = mix(tex.rgb, outlineColor.rgb, outlineColor.a);
}
if (coord0.y < radius - 1.0) {
if (coord0.x < radius - 1.0)
tex = shapeCorner(coord0, tex, vec2(radius-1.0, radius-1.0));
else if (coord0.x > windowSize.x - radius + 1.0)
tex = shapeCorner(coord0, tex, vec2(windowSize.x - radius+1.0, radius-1.0));
else if (coord0.y < outlineThickness - 1.0)
tex = shapeCorner(coord0, tex, vec2(coord0.x, radius-1.0));
}
else if (coord0.y > windowSize.y - radius) {
if (coord0.x < radius - 1.0)
tex = shapeCorner(coord0, tex, vec2(radius-1.0, windowSize.y - radius+1.0));
else if (coord0.x > windowSize.x - radius + 1.0)
tex = shapeCorner(coord0, tex, vec2(windowSize.x - radius+1.0, windowSize.y - radius+1.0));
else if (coord0.y > windowSize.y - outlineThickness + 1.0)
tex = shapeCorner(coord0, tex, vec2(coord0.x, windowSize.y - radius+1.0));
}
else {
if (coord0.x < radius - 1.0)
tex = shapeCorner(coord0, tex, vec2(radius-1.0, coord0.y));
else if (coord0.x > windowSize.x - radius + 1.0)
tex = shapeCorner(coord0, tex, vec2(windowSize.x - radius+1.0, coord0.y));
}

gl_FragColor = tex;
Expand Down
87 changes: 40 additions & 47 deletions shaders_140/shapecorners.frag
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,34 @@

uniform sampler2D front;
uniform float radius;
uniform bool windowActive;
uniform bool windowHasDecoration;
uniform vec2 windowSize;
uniform vec2 windowExpandedSize;
uniform vec2 windowTopLeft;
uniform vec4 shadowColor;
uniform float shadowSize;
uniform vec4 outlineColor;
uniform float outlineThickness;
uniform vec4 modulation;
uniform float saturation;

in vec2 texcoord0;
out vec4 fragColor;

bool isDrawingShadows() { return windowHasDecoration && shadowColor.a > 0.0; }
bool isDrawingOutline() { return outlineColor.a > 0.0 && outlineThickness > 0.0; }
bool isExtendedFrame(vec2 c) {
return c.x < -1 || c.x > windowSize.x+1
|| c.y < -1 || c.y > windowSize.y+1;
}

vec4 shadowCorner(float distance_from_center, bool isTopCorner) {
float r2 = radius * sqrt(2.0);
float percent;
if (windowActive) {
if (isTopCorner)
percent = (distance_from_center) / (r2 + 0.1*radius);
else
percent = (distance_from_center - 0.25*radius) / (r2 + 0.1*radius);
}
else {
if (isTopCorner)
percent = (distance_from_center + 0.55*radius) / (r2 + 0.5*radius);
else
percent = (distance_from_center) / (r2 + 0.1*radius);
}
return vec4(shadowColor.rgb, 1-percent);
vec4 shadowCorner(float distance_from_center) {
float percent = -distance_from_center/shadowSize + 1;
if(percent < 0)
return vec4(0,0,0,0);
else
return vec4(shadowColor.rgb, percent);
}

vec4 shapeCorner(vec2 coord0, vec4 tex, vec2 center, bool isTopCorner) {
vec4 shapeCorner(vec2 coord0, vec4 tex, vec2 center) {
float distance_from_center = distance(coord0, center);
vec4 c = isDrawingShadows() ? shadowCorner(distance_from_center, isTopCorner) : vec4(0,0,0,0);
vec4 c = isDrawingShadows() ? shadowCorner(distance_from_center) : vec4(0,0,0,0);

if(isDrawingOutline()) {
vec4 outlineOverlay = vec4(mix(tex.rgb, outlineColor.rgb, outlineColor.a), 1.0);
Expand All @@ -67,31 +55,36 @@ void main(void)
vec2 coord0 = vec2(texcoord0.x * windowExpandedSize.x - windowTopLeft.x,
(1-texcoord0.y)* windowExpandedSize.y - windowTopLeft.y);

if(!isExtendedFrame(coord0))
{
if (coord0.y < radius - 1) {
if (coord0.x < radius - 1)
tex = shapeCorner(coord0, tex, vec2(radius-1, radius-1), true);
else if (coord0.x > windowSize.x - radius + 1)
tex = shapeCorner(coord0, tex, vec2(windowSize.x - radius+1, radius-1), true);
else if (coord0.y < outlineThickness - 1)
tex.rgb = mix(tex.rgb, outlineColor.rgb, outlineColor.a);
}
else if (coord0.y > windowSize.y - radius + 1) {
if (coord0.x < radius - 1)
tex = shapeCorner(coord0, tex, vec2(radius-1, windowSize.y - radius+1), false);
else if (coord0.x > windowSize.x - radius + 1)
tex = shapeCorner(coord0, tex, vec2(windowSize.x - radius+1, windowSize.y - radius+1), false);
else if (coord0.y > windowSize.y - outlineThickness + 1)
tex.rgb = mix(tex.rgb, outlineColor.rgb, outlineColor.a);
}
else {
if (outlineColor.a > 0.0 && coord0.x < outlineThickness - 1)
tex.rgb = mix(tex.rgb, outlineColor.rgb, outlineColor.a);
else if (outlineColor.a > 0.0 && coord0.x > windowSize.x - outlineThickness + 1)
tex.rgb = mix(tex.rgb, outlineColor.rgb, outlineColor.a);
}
if (coord0.y < radius - 1) {
if (coord0.x < radius - 1)
tex = shapeCorner(coord0, tex, vec2(radius-1, radius-1));
else if (coord0.x > windowSize.x - radius + 1)
tex = shapeCorner(coord0, tex, vec2(windowSize.x - radius+1, radius-1));
else if (coord0.y < outlineThickness - 1)
tex = shapeCorner(coord0, tex, vec2(coord0.x, radius-1));
}
else if (coord0.y > windowSize.y - radius + 1) {
if (coord0.x < radius - 1)
tex = shapeCorner(coord0, tex, vec2(radius-1, windowSize.y - radius+1));
else if (coord0.x > windowSize.x - radius + 1)
tex = shapeCorner(coord0, tex, vec2(windowSize.x - radius+1, windowSize.y - radius+1));
else if (coord0.y > windowSize.y - outlineThickness + 1)
tex = shapeCorner(coord0, tex, vec2(coord0.x, windowSize.y - radius+1));
}
else {
if (coord0.x < radius - 1)
tex = shapeCorner(coord0, tex, vec2(radius-1, coord0.y));
else if (coord0.x > windowSize.x - radius + 1)
tex = shapeCorner(coord0, tex, vec2(windowSize.x - radius+1, coord0.y));
}

if (saturation != 1.0) {
vec3 desaturated = tex.rgb * vec3( 0.30, 0.59, 0.11 );
desaturated = vec3( dot( desaturated, tex.rgb ));
tex.rgb = tex.rgb * vec3( saturation ) + desaturated * vec3( 1.0 - saturation );
}
tex *= modulation;
tex.rgb *= tex.a;

fragColor = tex;
}
24 changes: 20 additions & 4 deletions shapecorners_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ ShapeCornersConfig::ShapeCornersConfig(QWidget* parent, const QVariantList& args
: KCModule(parent, args)
, ui(new ConfigDialog(this))
{
setAboutData(new KAboutData("ShapeCorners","ShapeCorners", "git"));
auto* layout = new QVBoxLayout(this);
layout->addWidget(ui);
setLayout(layout);
Expand All @@ -51,10 +50,15 @@ ShapeCornersConfig::load()
KCModule::load();
m_config.Load();
ui->roundness->setValue(m_config.m_size);

QColor shadowColor = m_config.m_shadowColor;
ui->drawShadowEnabled->setChecked(shadowColor.alpha() > 0);
shadowColor.setAlpha(255);
ui->shadowColor->setColor(shadowColor);
ui->activeShadowColor->setColor(m_config.m_shadowColor);
ui->inactiveShadowColor->setColor(m_config.m_inactiveShadowColor);
ui->activeShadowSize->setValue(m_config.m_shadowSize);
ui->inactiveShadowSize->setValue(m_config.m_inactiveShadowSize);

QColor outlineColor = m_config.m_outlineColor;
QColor inactiveOutlineColor = m_config.m_inactiveOutlineColor;
ui->drawOutlineEnabled->setChecked(outlineColor.alpha() > 0);
Expand All @@ -69,8 +73,14 @@ ShapeCornersConfig::save()
{
KCModule::save();
m_config.m_size = ui->roundness->value();
m_config.m_shadowColor = ui->shadowColor->color();

m_config.m_shadowColor = ui->activeShadowColor->color();
m_config.m_shadowColor.setAlpha(ui->drawShadowEnabled->isChecked()? 255: 0);
m_config.m_shadowSize = ui->activeShadowSize->value();
m_config.m_inactiveShadowColor = ui->inactiveShadowColor->color();
m_config.m_inactiveShadowColor.setAlpha(ui->drawShadowEnabled->isChecked()? 255: 0);
m_config.m_inactiveShadowSize = ui->inactiveShadowSize->value();

m_config.m_outlineColor = ui->outlineColor->color();
m_config.m_inactiveOutlineColor = ui->inactiveOutlineColor->color();
if(!ui->drawOutlineEnabled->isChecked()){
Expand All @@ -91,11 +101,17 @@ void
ShapeCornersConfig::defaults()
{
KCModule::defaults();
m_config = ConfigModel();
ui->roundness->setValue(m_config.m_size);

QColor shadowColor = m_config.m_shadowColor;
ui->drawShadowEnabled->setChecked(shadowColor.alpha() > 0);
shadowColor.setAlpha(255);
ui->shadowColor->setColor(shadowColor);
ui->activeShadowColor->setColor(m_config.m_shadowColor);
ui->inactiveShadowColor->setColor(m_config.m_inactiveShadowColor);
ui->activeShadowSize->setValue(m_config.m_shadowSize);
ui->inactiveShadowSize->setValue(m_config.m_inactiveShadowSize);

QColor outlineColor = m_config.m_outlineColor;
QColor inactiveOutlineColor = m_config.m_inactiveOutlineColor;
ui->drawOutlineEnabled->setChecked(outlineColor.alpha() > 0);
Expand Down
Loading

0 comments on commit 923f705

Please sign in to comment.