From 37ea85f1bd9d8cabf44c5918e77f03be070bb1ea Mon Sep 17 00:00:00 2001
From: YuraIz <7516890@gmail.com>
Date: Thu, 4 Aug 2022 11:47:38 +0300
Subject: [PATCH] added smooth corners preference
---
src/effect/rounded-corners-effect.ts | 5 +-
src/effect/shader/rounded_corners.frag | 86 +++++++++++++------
src/manager/rounded-corners-manager.ts | 5 ++
.../widgets/rounded-corners-item.ts | 5 ++
.../widgets/rounded-corners-item.ui | 40 +++++++++
src/utils/types.ts | 1 +
6 files changed, 115 insertions(+), 27 deletions(-)
diff --git a/src/effect/rounded-corners-effect.ts b/src/effect/rounded-corners-effect.ts
index 09a8e1b..f585ea0 100644
--- a/src/effect/rounded-corners-effect.ts
+++ b/src/effect/rounded-corners-effect.ts
@@ -22,6 +22,7 @@ const { declarations, code } = loadShader (
class Uniforms {
bounds = 0
clip_radius = 0
+ smoothing = 0
inner_bounds = 0
inner_clip_radius = 0
pixel_step = 0
@@ -54,6 +55,7 @@ export default registerClass (
Effect.uniforms = {
bounds: 0,
clip_radius: 0,
+ smoothing: 0,
inner_bounds: 0,
inner_clip_radius: 0,
pixel_step: 0,
@@ -123,7 +125,7 @@ export default registerClass (
const border_color = border.color
const radius = corners_cfg.border_radius * scale_factor
- const { padding } = corners_cfg
+ const { padding, smoothing } = corners_cfg
const bounds = [
outer_bounds.x1 + padding.left * scale_factor,
@@ -152,6 +154,7 @@ export default registerClass (
this.set_uniform_float (location.inner_bounds, 4, inner_bounds)
this.set_uniform_float (location.pixel_step, 2, pixel_step)
this.set_uniform_float (location.border_width, 1, [border_width])
+ this.set_uniform_float (location.smoothing, 1, [smoothing])
this.set_uniform_float (location.clip_radius, 1, [radius])
this.set_uniform_float (location.border_color, 4, border_color)
this.set_uniform_float (location.inner_clip_radius, 1, [
diff --git a/src/effect/shader/rounded_corners.frag b/src/effect/shader/rounded_corners.frag
index 513b8a6..01f17f6 100644
--- a/src/effect/shader/rounded_corners.frag
+++ b/src/effect/shader/rounded_corners.frag
@@ -4,8 +4,6 @@
// With a litte change to make it works well with windows
// The uniforms variables for controls
-// varying vec2 vsPos;
-
uniform vec4 bounds; // x, y: top left; z, w: bottom right
uniform float clip_radius;
uniform vec4 inner_bounds;
@@ -14,58 +12,94 @@ uniform vec2 pixel_step;
uniform float skip;
uniform float border_width;
uniform vec4 border_color;
+uniform float smoothing;
+
+
+float circle_bounds(vec2 p, vec2 center, float clip_radius) {
+ vec2 delta = p - vec2(center.x, center.y);
+ float dist_squared = dot(delta, delta);
+
+ // Fully outside the circle
+ float outer_radius = clip_radius + 0.5;
+ if(dist_squared >= (outer_radius * outer_radius))
+ return 0.0;
+
+ // Fully inside the circle
+ float inner_radius = clip_radius - 0.5;
+ if(dist_squared <= (inner_radius * inner_radius))
+ return 1.0;
+
+ // Only pixels on the edge of the curve need expensive antialiasing
+ return outer_radius - sqrt(dist_squared);
+}
+
+float squircle_bounds(vec2 p, vec2 center, float clip_radius, float exponent) {
+ vec2 delta = abs(p - center);
+
+ float pow_dx = pow(delta.x, exponent);
+ float pow_dy = pow(delta.y, exponent);
+
+ float dist = pow(pow_dx + pow_dy, 1.0 / exponent);
+
+ return clamp(clip_radius - dist + 0.5, 0.0, 1.0);
+}
-float rounded_rect_coverage(vec2 p, vec4 bounds, float clip_radius) {
+float rounded_rect_coverage(vec2 p, vec4 bounds, float clip_radius, float exponent) {
// Outside the bounds
if(p.x < bounds.x || p.x > bounds.z || p.y < bounds.y || p.y > bounds.w) {
return 0.0;
}
+
+ vec2 center;
+
float center_left = bounds.x + clip_radius;
float center_right = bounds.z - clip_radius;
- float center_x;
if(p.x < center_left)
- center_x = center_left;
+ center.x = center_left;
else if(p.x > center_right)
- center_x = center_right;
+ center.x = center_right;
else
return 1.0; // The vast majority of pixels exit early here
float center_top = bounds.y + clip_radius;
float center_bottom = bounds.w - clip_radius;
- float center_y;
if(p.y < center_top)
- center_y = center_top;
+ center.y = center_top;
else if(p.y > center_bottom)
- center_y = center_bottom;
+ center.y = center_bottom;
else
return 1.0;
+
+ if(exponent <= 2.0) {
+ return circle_bounds(p, center, clip_radius);
+ } else {
+ return squircle_bounds(p, center, clip_radius, exponent);
+ }
+}
- vec2 delta = p - vec2(center_x, center_y);
- float dist_squared = dot(delta, delta);
+void main() {
+ if(skip < 1.0) {
+
+ float exponent = smoothing * 10.0 + 2.0;
- // Fully outside the circle
- float outer_radius = clip_radius + 0.5;
- if(dist_squared >= (outer_radius * outer_radius))
- return 0.0;
+ float radius = clip_radius * 0.5 * exponent;
- // Fully inside the circle
- float inner_radius = clip_radius - 0.5;
- if(dist_squared <= (inner_radius * inner_radius))
- return 1.0;
+ float max_radius = min(bounds.z - bounds.x, bounds.w - bounds.y) * 0.5;
- // Only pixels on the edge of the curve need expensive antialiasing
- return outer_radius - sqrt(dist_squared);
-}
+ if(radius > max_radius) {
+ exponent *= max_radius / radius;
+ radius = max_radius;
+ }
+
+ float inner_radius = inner_clip_radius * (radius / clip_radius);
-void main() {
- if(skip < 1.0) {
vec2 texture_coord = cogl_tex_coord0_in.xy / pixel_step;
- float outer_alpha = rounded_rect_coverage(texture_coord, bounds, clip_radius);
+ float outer_alpha = rounded_rect_coverage(texture_coord, bounds, radius, exponent);
if(border_width > 0.1) {
- float inner_alpha = rounded_rect_coverage(texture_coord, inner_bounds, inner_clip_radius);
+ float inner_alpha = rounded_rect_coverage(texture_coord, inner_bounds, inner_radius, exponent);
float border_alpha = clamp(outer_alpha - inner_alpha, 0.0, 1.0) * cogl_color_out.a;
cogl_color_out = mix(cogl_color_out, vec4(border_color.rgb, 1.0), border_alpha * border_color.a);
diff --git a/src/manager/rounded-corners-manager.ts b/src/manager/rounded-corners-manager.ts
index 01ba4b8..81e7ada 100644
--- a/src/manager/rounded-corners-manager.ts
+++ b/src/manager/rounded-corners-manager.ts
@@ -249,6 +249,11 @@ export class RoundedCornersManager {
}
const { left, right, top, bottom } = padding
+ // Increasing border_radius when smoothing is on
+ if (this.global_rounded_corners !== null) {
+ border_radius *= 1.0 + this.global_rounded_corners.smoothing
+ }
+
// Sadly, the scale of style of St.Widget may be different between scale
// of window if there are two monitor with different scale factor.
// - Scale of Style always as same as primary monitor
diff --git a/src/preferences/widgets/rounded-corners-item.ts b/src/preferences/widgets/rounded-corners-item.ts
index 732242c..3a76b5d 100644
--- a/src/preferences/widgets/rounded-corners-item.ts
+++ b/src/preferences/widgets/rounded-corners-item.ts
@@ -16,6 +16,7 @@ export default GObject.registerClass (
InternalChildren: [
'rounded_in_maximized_switch',
'border_radius_scale',
+ 'smoothing_scale',
'padding_left_scale',
'padding_right_scale',
'padding_top_scale',
@@ -28,6 +29,7 @@ export default GObject.registerClass (
class extends Gtk.ListBox {
private _rounded_in_maximized_switch !: Gtk.Switch
private _border_radius_scale !: Gtk.Scale
+ private _smoothing_scale !: Gtk.Scale
private _padding_left_scale !: Gtk.Scale
private _padding_right_scale !: Gtk.Scale
private _padding_top_scale !: Gtk.Scale
@@ -43,6 +45,7 @@ export default GObject.registerClass (
super._init ()
this._scales = [
this._border_radius_scale,
+ this._smoothing_scale,
this._padding_bottom_scale,
this._padding_left_scale,
this._padding_right_scale,
@@ -90,6 +93,7 @@ export default GObject.registerClass (
},
keep_rounded_corners: this._rounded_in_maximized_switch.active,
border_radius: this._border_radius_scale.get_value (),
+ smoothing: this._smoothing_scale.get_value (),
enabled: true,
}
}
@@ -97,6 +101,7 @@ export default GObject.registerClass (
set cfg (cfg: RoundedCornersCfg) {
this._rounded_in_maximized_switch.active = cfg.keep_rounded_corners
this._border_radius_scale.set_value (cfg.border_radius)
+ this._smoothing_scale.set_value (cfg.smoothing)
this._padding_left_scale.set_value (cfg.padding.left)
this._padding_right_scale.set_value (cfg.padding.right)
this._padding_top_scale.set_value (cfg.padding.top)
diff --git a/src/preferences/widgets/rounded-corners-item.ui b/src/preferences/widgets/rounded-corners-item.ui
index 975eee4..812e876 100644
--- a/src/preferences/widgets/rounded-corners-item.ui
+++ b/src/preferences/widgets/rounded-corners-item.ui
@@ -37,6 +37,40 @@
+
+
+
@@ -270,6 +304,12 @@
40
1
1
+
+
+ 0
+ 1
+ 0.1
+ 0.1
0
diff --git a/src/utils/types.ts b/src/utils/types.ts
index e656377..00b3e6c 100644
--- a/src/utils/types.ts
+++ b/src/utils/types.ts
@@ -17,6 +17,7 @@ export class Padding {
export interface RoundedCornersCfg {
keep_rounded_corners: boolean
border_radius: number
+ smoothing: number
padding: Padding
enabled: boolean
}