mirror of
https://github.com/yshui/picom.git
synced 2025-04-14 17:53:25 -04:00
non-experimental backend changes
This commit is contained in:
parent
9dfa6056d8
commit
76992fd26e
12 changed files with 106 additions and 287 deletions
|
@ -109,6 +109,12 @@ OPTIONS
|
|||
*--rounded-corners-exclude* 'CONDITION'::
|
||||
Exclude conditions for rounded corners.
|
||||
|
||||
*--round-borders* 'VALUE'::
|
||||
When rounding corners, Round the borders of windows. (defaults to 1).
|
||||
|
||||
*--round-borders-exclude* 'CONDITION'::
|
||||
Exclude conditions for rounding borders.
|
||||
|
||||
*--mark-wmwin-focused*::
|
||||
Try to detect WM windows (a non-override-redirect window with no child that has 'WM_STATE') and mark them as active.
|
||||
|
||||
|
|
|
@ -345,11 +345,13 @@ typedef struct session {
|
|||
/// Whether X Present extension exists.
|
||||
bool present_exists;
|
||||
/// Whether X GLX extension exists.
|
||||
#ifdef CONFIG_OPENGL
|
||||
bool glx_exists;
|
||||
/// Event base number for X GLX extension.
|
||||
int glx_event;
|
||||
/// Error base number for X GLX extension.
|
||||
int glx_error;
|
||||
#endif
|
||||
/// Whether X Xinerama extension exists.
|
||||
bool xinerama_exists;
|
||||
/// Xinerama screen regions.
|
||||
|
|
|
@ -576,7 +576,8 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable,
|
|||
|
||||
.track_leader = false,
|
||||
|
||||
.rounded_corners_blacklist = NULL
|
||||
.rounded_corners_blacklist = NULL,
|
||||
.round_borders_blacklist = NULL
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
|
|
@ -221,6 +221,10 @@ typedef struct options {
|
|||
int corner_radius;
|
||||
/// Rounded corners blacklist. A linked list of conditions.
|
||||
c2_lptr_t *rounded_corners_blacklist;
|
||||
/// Do we round the borders of rounded windows?
|
||||
int round_borders;
|
||||
/// Rounded borders blacklist. A linked list of conditions.
|
||||
c2_lptr_t *round_borders_blacklist;
|
||||
|
||||
// === Focus related ===
|
||||
/// Whether to try to detect WM windows and mark them as focused.
|
||||
|
|
|
@ -378,6 +378,10 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
|
|||
config_lookup_int(&cfg, "corner-radius", &opt->corner_radius);
|
||||
// --rounded-corners-exclude
|
||||
parse_cfg_condlst(&cfg, &opt->rounded_corners_blacklist, "rounded-corners-exclude");
|
||||
// --round-borders
|
||||
config_lookup_int(&cfg, "round-borders", &opt->round_borders);
|
||||
// --round-borders-exclude
|
||||
parse_cfg_condlst(&cfg, &opt->round_borders_blacklist, "round-borders-exclude");
|
||||
// -e (frame_opacity)
|
||||
config_lookup_float(&cfg, "frame-opacity", &opt->frame_opacity);
|
||||
// -c (shadow_enable)
|
||||
|
@ -463,6 +467,7 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
|
|||
}
|
||||
lcfg_lookup_bool(&cfg, "vsync", &opt->vsync);
|
||||
// --backend
|
||||
lcfg_lookup_bool(&cfg, "experimental-backends", &opt->experimental_backends);
|
||||
if (config_lookup_string(&cfg, "backend", &sval)) {
|
||||
opt->backend = parse_backend(sval);
|
||||
if (opt->backend >= NUM_BKEND) {
|
||||
|
|
313
src/opengl.c
313
src/opengl.c
|
@ -459,7 +459,7 @@ glx_init_frag_shader_corners(glx_round_pass_t *ppass, const int shader_idx,
|
|||
pc += strlen(pc);
|
||||
assert(strlen(shader_str) < len);
|
||||
|
||||
sprintf(pc, SHADER_STR);
|
||||
sprintf(pc, "%s", SHADER_STR);
|
||||
assert(strlen(shader_str) < len);
|
||||
#ifdef DEBUG_GLX
|
||||
log_debug("Generated rounded corners shader %d:\n%s\n", shader_idx, shader_str);
|
||||
|
@ -557,44 +557,10 @@ bool glx_init_rounded_corners(session_t *ps) {
|
|||
"we set it to background texture\n"
|
||||
"\n";
|
||||
|
||||
// Fragment shader (round corners)
|
||||
// dst0 shader
|
||||
static const char *FRAG_SHADER_ROUND_CORNERS_0 =
|
||||
" float u_fRadiusPx = u_radius;\n"
|
||||
" float u_fHalfBorderThickness = u_borderw / 2.0;\n"
|
||||
" //v4FromColor = u_v4BorderColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
|
||||
" //u_v4FillColor = vec4(0.0, 0.0, 0.0, 0.0); // Inside rect "
|
||||
"color\n"
|
||||
|
||||
"\n"
|
||||
" vec2 u_v2HalfShapeSizePx = u_texsize/2.0 - "
|
||||
"vec2(u_fHalfBorderThickness);\n"
|
||||
" vec2 v_v2CenteredPos = (gl_FragCoord.xy - u_texsize.xy / 2.0 - "
|
||||
"coord);\n"
|
||||
"\n"
|
||||
" float fDist = RectSDF(v_v2CenteredPos, u_v2HalfShapeSizePx, "
|
||||
"u_fRadiusPx - u_fHalfBorderThickness);\n"
|
||||
" if (u_fHalfBorderThickness > 0.0) {\n"
|
||||
" if (fDist < 0.0) {\n"
|
||||
" v4ToColor = u_v4FillColor;\n"
|
||||
" }\n"
|
||||
" fDist = abs(fDist) - u_fHalfBorderThickness;\n"
|
||||
" } else {\n"
|
||||
" v4FromColor = u_v4FillColor;\n"
|
||||
" }\n"
|
||||
" float fBlendAmount = clamp(fDist + 0.5, 0.0, 1.0);\n"
|
||||
" //vec4 c = fDist <= 0.0 ? v4FromColor : v4ToColor;\n"
|
||||
" vec4 c = mix(v4FromColor, v4ToColor, fBlendAmount);\n"
|
||||
"\n"
|
||||
" // final color\n"
|
||||
" if ( c == vec4(0.0,0.0,0.0,0.0) ) discard; else\n"
|
||||
" gl_FragColor = c;\n"
|
||||
"}\n";
|
||||
|
||||
// Fragment shader (round corners)
|
||||
// dst1 shader
|
||||
static const char *FRAG_SHADER_ROUND_CORNERS_1 =
|
||||
" float u_fRadiusPx = u_radius + 25.0;\n"
|
||||
static const char *FRAG_SHADER_ROUND_CORNERS =
|
||||
" float u_fRadiusPx = u_radius;\n"
|
||||
" float u_fHalfBorderThickness = u_borderw / 2.0;\n"
|
||||
" //float u_fHalfBorderThickness = 20.0 /2.0;\n"
|
||||
" //u_v4FillColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
|
||||
|
@ -616,11 +582,11 @@ bool glx_init_rounded_corners(session_t *ps) {
|
|||
" } else {\n"
|
||||
" v4FromColor = u_v4FillColor;\n"
|
||||
" }\n"
|
||||
" float fBlendAmount = clamp(fDist + 0.5, 0.0, 1.0);\n"
|
||||
" float fBlendAmount = smoothstep(-1.0, 1.0, fDist);\n"
|
||||
" vec4 c = mix(v4FromColor, v4ToColor, fBlendAmount);"
|
||||
"\n"
|
||||
" // final color\n"
|
||||
" if ( c == vec4(0.0,0.0,0.0,0.0) ) discard; else\n"
|
||||
" //if ( c == vec4(0.0,0.0,0.0,0.0) ) discard; else\n"
|
||||
" gl_FragColor = c;\n"
|
||||
" //gl_FragColor = vec4(vec3(fBlendAmount), 1.0);\n"
|
||||
" //gl_FragColor = vec4(vec3(abs(dist) / (2.0 * corner)), 1.0);\n"
|
||||
|
@ -640,7 +606,7 @@ bool glx_init_rounded_corners(session_t *ps) {
|
|||
|
||||
if (!glx_init_frag_shader_corners(
|
||||
&ps->psglx->round_passes[0], 0, FRAG_SHADER_PREFIX,
|
||||
FRAG_SHADER_ROUND_CORNERS_0, extension, sampler_type, texture_func)) {
|
||||
FRAG_SHADER_ROUND_CORNERS, extension, sampler_type, texture_func)) {
|
||||
|
||||
log_error("Failed to create rounded corners fragment shader "
|
||||
"PRE.");
|
||||
|
@ -650,18 +616,6 @@ bool glx_init_rounded_corners(session_t *ps) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!glx_init_frag_shader_corners(
|
||||
&ps->psglx->round_passes[1], 1, FRAG_SHADER_PREFIX,
|
||||
FRAG_SHADER_ROUND_CORNERS_1, extension, sampler_type, texture_func)) {
|
||||
|
||||
log_error("Failed to create rounded corners fragment shader "
|
||||
"POST.");
|
||||
setlocale(LC_NUMERIC, lc_numeric_old);
|
||||
free(lc_numeric_old);
|
||||
free(extension);
|
||||
return false;
|
||||
}
|
||||
|
||||
free(extension);
|
||||
|
||||
// Restore LC_NUMERIC
|
||||
|
@ -735,7 +689,7 @@ bool glx_bind_texture(session_t *ps attr_unused, glx_texture_t **pptex, int x, i
|
|||
|
||||
glx_texture_t *ptex = *pptex;
|
||||
|
||||
// log_trace("Copying xy(%d %d) wh(%d %d)", x, y, width, height);
|
||||
// log_trace("Copying xy(%d %d) wh(%d %d) ptex(%p)", x, y, width, height, ptex);
|
||||
|
||||
// Release texture if parameters are inconsistent
|
||||
if (ptex && ptex->texture && (ptex->width != width || ptex->height != height)) {
|
||||
|
@ -1260,20 +1214,43 @@ glx_blur_dst_end:
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool glx_read_border_pixel(session_t *ps, struct managed_win *w, int x, int y,
|
||||
int width attr_unused, int height, float *ppixel) {
|
||||
// TODO: this is a mess and needs a more consistent way of getting the border pixel
|
||||
// I tried looking for a notify event for XCB_CW_BORDER_PIXEL (in xcb_create_window())
|
||||
// or a way to get the pixels from xcb_render_picture_t but the documentation for
|
||||
// the xcb_xrender extension is literaly non existent...
|
||||
bool glx_read_border_pixel(struct managed_win *w, int root_height, int x, int y,
|
||||
int width attr_unused, int height, int cr, float *ppixel) {
|
||||
if (!ppixel)
|
||||
return false;
|
||||
|
||||
// First try bottom left corner
|
||||
auto openglx = x;
|
||||
auto opengly = ps->root_height - height - y;
|
||||
// First try bottom left corner past the
|
||||
// circle radius (after the rounded corner ends)
|
||||
auto openglx = x + cr * 2;
|
||||
auto opengly = root_height - height - y;
|
||||
|
||||
// X is out of bounds
|
||||
// move to the right side
|
||||
if (openglx < 0)
|
||||
openglx = x + width - cr;
|
||||
|
||||
// Y is out of bounds
|
||||
// move to to top part
|
||||
if (opengly < 0) {
|
||||
opengly += height - 1;
|
||||
}
|
||||
|
||||
// bottom left corner is out of bounds
|
||||
// use top border line instead
|
||||
if (openglx < 0 && opengly < 0) {
|
||||
// openglx = x + width;
|
||||
opengly += height - 1;
|
||||
if (openglx < 0 || opengly < 0) {
|
||||
|
||||
// log_warn("OUT OF BOUNDS: xy(%d, %d), glxy(%d %d) wh(%d %d),
|
||||
// border_col(%.2f, %.2f, %.2f, %.2f)", x, y, openglx, opengly, width,
|
||||
//height, (float)w->border_col[0], (float)w->border_col[1],
|
||||
//(float)w->border_col[2], (float)w->border_col[3]);
|
||||
|
||||
// Reset the color so the shader doesn't use it
|
||||
w->border_col[0] = w->border_col[1] = w->border_col[2] =
|
||||
w->border_col[3] = -1.0;
|
||||
}
|
||||
|
||||
// Invert Y-axis so we can query border color from texture (0,0)
|
||||
|
@ -1289,218 +1266,23 @@ bool glx_read_border_pixel(session_t *ps, struct managed_win *w, int x, int y,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool glx_round_corners_dst0(session_t *ps, struct managed_win *w,
|
||||
const glx_texture_t *ptex attr_unused, int shader_idx, int dx,
|
||||
int dy, int width, int height, float z, float cr,
|
||||
const region_t *reg_tgt attr_unused, glx_blur_cache_t *pbc) {
|
||||
|
||||
assert(shader_idx >= 0 && shader_idx <= 1);
|
||||
assert(ps->psglx->round_passes[0].prog);
|
||||
assert(ps->psglx->round_passes[1].prog);
|
||||
const bool have_scissors = glIsEnabled(GL_SCISSOR_TEST);
|
||||
const bool have_stencil = glIsEnabled(GL_STENCIL_TEST);
|
||||
bool ret = false;
|
||||
|
||||
// log_warn("dxy(%d, %d) wh(%d %d) rwh(%d %d) bw(%d)",
|
||||
// dx, dy, width, height, ps->root_width, ps->root_height,
|
||||
//w->g.border_width);
|
||||
|
||||
if (w->g.border_width >= 1 && w->border_col[0] == -1.0) {
|
||||
glx_read_border_pixel(ps, w, dx, dy, width, height, &w->border_col[0]);
|
||||
}
|
||||
|
||||
// Calculate copy region size
|
||||
glx_blur_cache_t ibc = {.width = 0, .height = 0};
|
||||
if (!pbc)
|
||||
pbc = &ibc;
|
||||
|
||||
int mdx = dx, mdy = dy, mwidth = width, mheight = height;
|
||||
// log_trace("%d, %d, %d, %d", mdx, mdy, mwidth, mheight);
|
||||
|
||||
GLenum tex_tgt = GL_TEXTURE_RECTANGLE;
|
||||
if (ps->psglx->has_texture_non_power_of_two)
|
||||
tex_tgt = GL_TEXTURE_2D;
|
||||
|
||||
// Free textures if size inconsistency discovered
|
||||
if (mwidth != pbc->width || mheight != pbc->height)
|
||||
free_glx_bc_resize(ps, pbc);
|
||||
|
||||
// Generate FBO and textures if needed
|
||||
if (!pbc->textures[0])
|
||||
pbc->textures[0] = glx_gen_texture(tex_tgt, mwidth, mheight);
|
||||
GLuint tex_scr = pbc->textures[0];
|
||||
|
||||
pbc->width = mwidth;
|
||||
pbc->height = mheight;
|
||||
|
||||
if (!tex_scr) {
|
||||
log_error("Failed to allocate texture.");
|
||||
goto glx_round_corners_dst_end;
|
||||
}
|
||||
|
||||
// Read destination pixels into a texture
|
||||
glEnable(tex_tgt);
|
||||
glBindTexture(tex_tgt, tex_scr);
|
||||
glx_copy_region_to_tex(ps, tex_tgt, mdx, mdy, mdx, mdy, mwidth, mheight);
|
||||
|
||||
// Texture scaling factor
|
||||
GLfloat texfac_x = 1.0f, texfac_y = 1.0f;
|
||||
if (tex_tgt == GL_TEXTURE_2D) {
|
||||
texfac_x /= (GLfloat)mwidth;
|
||||
texfac_y /= (GLfloat)mheight;
|
||||
}
|
||||
|
||||
// Paint it back
|
||||
{
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
{
|
||||
const glx_round_pass_t *ppass = &ps->psglx->round_passes[shader_idx];
|
||||
assert(ppass->prog);
|
||||
|
||||
assert(tex_scr);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(tex_tgt, tex_scr);
|
||||
|
||||
// If caller specified a texture use it as source
|
||||
if (ptex) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(ptex->target, ptex->texture);
|
||||
} else {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(tex_tgt, tex_scr);
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDrawBuffer(GL_BACK);
|
||||
if (have_scissors)
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
if (have_stencil)
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
// Our shader generates a transparent mid section
|
||||
// with opaque corners copied from the background texture
|
||||
// We must use blending to get the window pixesl to appear
|
||||
// glDisable(GL_BLEND);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
|
||||
glUseProgram(ppass->prog);
|
||||
|
||||
if (ppass->unifm_tex_scr >= 0)
|
||||
glUniform1i(ppass->unifm_tex_scr, (GLint)0);
|
||||
if (ppass->unifm_tex_wnd >= 0)
|
||||
glUniform1i(ppass->unifm_tex_wnd, (GLint)1);
|
||||
|
||||
if (ppass->unifm_radius >= 0)
|
||||
glUniform1f(ppass->unifm_radius, cr);
|
||||
if (ppass->unifm_texcoord >= 0)
|
||||
glUniform2f(ppass->unifm_texcoord, (float)dx, (float)dy);
|
||||
if (ppass->unifm_texsize >= 0)
|
||||
glUniform2f(ppass->unifm_texsize, (float)mwidth, (float)mheight);
|
||||
if (ppass->unifm_borderw >= 0)
|
||||
glUniform1f(ppass->unifm_borderw,
|
||||
(w->border_col[0] != -1.) ? w->g.border_width : 0);
|
||||
if (ppass->unifm_borderc >= 0)
|
||||
glUniform4fv(ppass->unifm_borderc, 1, (GLfloat *)&w->border_col[0]);
|
||||
if (ppass->unifm_resolution >= 0)
|
||||
glUniform2f(ppass->unifm_resolution, (float)ps->root_width,
|
||||
(float)ps->root_height);
|
||||
|
||||
// Painting
|
||||
{
|
||||
P_PAINTREG_START(crect) {
|
||||
// XXX explain these variables
|
||||
auto rx = (GLfloat)(crect.x1 - dx);
|
||||
auto ry = (GLfloat)(crect.y1 - dy);
|
||||
auto rxe = rx + (GLfloat)(crect.x2 - crect.x1);
|
||||
auto rye = ry + (GLfloat)(crect.y2 - crect.y1);
|
||||
// Rectangle textures have [0-w] [0-h] while 2D texture
|
||||
// has [0-1] [0-1] Thanks to amonakov for pointing out!
|
||||
if (GL_TEXTURE_2D == tex_tgt) {
|
||||
rx = rx / (GLfloat)width;
|
||||
ry = ry / (GLfloat)height;
|
||||
rxe = rxe / (GLfloat)width;
|
||||
rye = rye / (GLfloat)height;
|
||||
}
|
||||
auto rdx = (GLfloat)crect.x1;
|
||||
auto rdy = (GLfloat)(ps->root_height - crect.y1);
|
||||
auto rdxe = (GLfloat)rdx + (GLfloat)(crect.x2 - crect.x1);
|
||||
auto rdye = (GLfloat)rdy - (GLfloat)(crect.y2 - crect.y1);
|
||||
|
||||
// Invert Y if needed, this may not work as expected,
|
||||
// though. I don't have such a FBConfig to test with.
|
||||
// if (ptex && !ptex->y_inverted) {
|
||||
{
|
||||
ry = 1.0f - ry;
|
||||
rye = 1.0f - rye;
|
||||
}
|
||||
|
||||
// log_trace("Rect %d (i:%d): %f, %f, %f, %f -> %f, %f,
|
||||
// %f, %f", ri ,ptex ? ptex->y_inverted : -1, rx, ry,
|
||||
// rxe,
|
||||
// rye, rdx, rdy, rdxe, rdye);
|
||||
|
||||
glTexCoord2f(rx, ry);
|
||||
glVertex3f(rdx, rdy, z);
|
||||
|
||||
glTexCoord2f(rxe, ry);
|
||||
glVertex3f(rdxe, rdy, z);
|
||||
|
||||
glTexCoord2f(rxe, rye);
|
||||
glVertex3f(rdxe, rdye, z);
|
||||
|
||||
glTexCoord2f(rx, rye);
|
||||
glVertex3f(rdx, rdye, z);
|
||||
}
|
||||
P_PAINTREG_END();
|
||||
}
|
||||
|
||||
glUseProgram(0);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
glx_round_corners_dst_end:
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glBindTexture(tex_tgt, 0);
|
||||
glDisable(tex_tgt);
|
||||
if (have_scissors)
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
if (have_stencil)
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
if (&ibc == pbc) {
|
||||
free_glx_bc(ps, pbc);
|
||||
}
|
||||
|
||||
gl_check_err();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool glx_round_corners_dst1(session_t *ps, struct managed_win *w, const glx_texture_t *ptex,
|
||||
int shader_idx, int dx, int dy, int width, int height,
|
||||
float z, float cr, const region_t *reg_tgt attr_unused,
|
||||
glx_blur_cache_t *pbc attr_unused) {
|
||||
bool glx_round_corners_dst(session_t *ps, struct managed_win *w, const glx_texture_t *ptex,
|
||||
int dx, int dy, int width, int height, float z, float cr,
|
||||
const region_t *reg_tgt attr_unused,
|
||||
glx_blur_cache_t *pbc attr_unused) {
|
||||
|
||||
assert(shader_idx >= 0 && shader_idx <= 1);
|
||||
assert(ps->psglx->round_passes[0].prog);
|
||||
assert(ps->psglx->round_passes[1].prog);
|
||||
bool ret = false;
|
||||
|
||||
if (w->g.border_width >= 1 && w->border_col[0] == -1.0) {
|
||||
glx_read_border_pixel(ps, w, dx, dy, width, height, &w->border_col[0]);
|
||||
if (w->g.border_width >= 1 /*&& w->border_col[0] == -1.0*/) {
|
||||
glx_read_border_pixel(w, ps->root_height, dx, dy, width, height,
|
||||
w->corner_radius, &w->border_col[0]);
|
||||
}
|
||||
|
||||
{
|
||||
const glx_round_pass_t *ppass = &ps->psglx->round_passes[shader_idx];
|
||||
const glx_round_pass_t *ppass = &ps->psglx->round_passes[0];
|
||||
assert(ppass->prog);
|
||||
|
||||
// If caller specified a texture use it as source
|
||||
|
@ -1528,7 +1310,8 @@ bool glx_round_corners_dst1(session_t *ps, struct managed_win *w, const glx_text
|
|||
glUniform2f(ppass->unifm_texsize, (float)width, (float)height);
|
||||
if (ppass->unifm_borderw >= 0)
|
||||
glUniform1f(ppass->unifm_borderw,
|
||||
(w->border_col[0] != -1.) ? w->g.border_width : 0);
|
||||
(w->round_borders && w->border_col[0] != -1.) ? w->g.border_width
|
||||
: 0);
|
||||
if (ppass->unifm_borderc >= 0)
|
||||
glUniform4fv(ppass->unifm_borderc, 1, (GLfloat *)&w->border_col[0]);
|
||||
if (ppass->unifm_resolution >= 0)
|
||||
|
|
10
src/opengl.h
10
src/opengl.h
|
@ -137,13 +137,9 @@ void glx_set_clip(session_t *ps, const region_t *reg);
|
|||
bool glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z,
|
||||
GLfloat factor_center, const region_t *reg_tgt, glx_blur_cache_t *pbc);
|
||||
|
||||
bool glx_round_corners_dst0(session_t *ps, struct managed_win *w, const glx_texture_t *ptex,
|
||||
int shader_idx, int dx, int dy, int width, int height, float z,
|
||||
float cr, const region_t *reg_tgt, glx_blur_cache_t *pbc);
|
||||
|
||||
bool glx_round_corners_dst1(session_t *ps, struct managed_win *w, const glx_texture_t *ptex,
|
||||
int shader_idx, int dx, int dy, int width, int height, float z,
|
||||
float cr, const region_t *reg_tgt, glx_blur_cache_t *pbc);
|
||||
bool glx_round_corners_dst(session_t *ps, struct managed_win *w, const glx_texture_t *ptex,
|
||||
int dx, int dy, int width, int height, float z, float cr,
|
||||
const region_t *reg_tgt, glx_blur_cache_t *pbc);
|
||||
|
||||
GLuint glx_create_shader(GLenum shader_type, const char *shader_str);
|
||||
|
||||
|
|
|
@ -124,6 +124,12 @@ static void usage(const char *argv0, int ret) {
|
|||
"--rounded-corners-exclude condition\n"
|
||||
" Exclude conditions for rounded corners.\n"
|
||||
"\n"
|
||||
"--round-borders value\n"
|
||||
" When rounding corners, round the borders of windows. (defaults to 1)\n"
|
||||
"\n"
|
||||
"--round-borders-exclude condition\n"
|
||||
" Exclude conditions for rounding borders.\n"
|
||||
"\n"
|
||||
"--mark-wmwin-focused\n"
|
||||
" Try to detect WM windows and mark them as active.\n"
|
||||
"\n"
|
||||
|
@ -449,6 +455,8 @@ static const struct option longopts[] = {
|
|||
{"shadow-color", required_argument, NULL, 332},
|
||||
{"corner-radius", required_argument, NULL, 333},
|
||||
{"rounded-corners-exclude", required_argument, NULL, 334},
|
||||
{"round-borders", required_argument, NULL, 335},
|
||||
{"round-borders-exclude", required_argument, NULL, 336},
|
||||
{"experimental-backends", no_argument, NULL, 733},
|
||||
{"monitor-repaint", no_argument, NULL, 800},
|
||||
{"diagnostics", no_argument, NULL, 801},
|
||||
|
@ -876,6 +884,14 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
|||
// --rounded-corners-exclude
|
||||
condlst_add(&opt->rounded_corners_blacklist, optarg);
|
||||
break;
|
||||
case 335:
|
||||
// --round-borders
|
||||
opt->round_borders = atoi(optarg);
|
||||
break;
|
||||
case 336:
|
||||
// --round-borders-exclude
|
||||
condlst_add(&opt->round_borders_blacklist, optarg);
|
||||
break;
|
||||
P_CASEBOOL(733, experimental_backends);
|
||||
P_CASEBOOL(800, monitor_repaint);
|
||||
case 801: opt->print_diagnostics = true; break;
|
||||
|
|
|
@ -1711,9 +1711,11 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
|||
.randr_exists = 0,
|
||||
.randr_event = 0,
|
||||
.randr_error = 0,
|
||||
#ifdef CONFIG_OPENGL
|
||||
.glx_exists = false,
|
||||
.glx_event = 0,
|
||||
.glx_error = 0,
|
||||
#endif
|
||||
.xrfilter_convolution_exists = false,
|
||||
|
||||
.atoms_wintypes = {0},
|
||||
|
@ -1917,6 +1919,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
|||
c2_list_postprocess(ps, ps->o.invert_color_list) &&
|
||||
c2_list_postprocess(ps, ps->o.opacity_rules) &&
|
||||
c2_list_postprocess(ps, ps->o.rounded_corners_blacklist) &&
|
||||
c2_list_postprocess(ps, ps->o.round_borders_blacklist) &&
|
||||
c2_list_postprocess(ps, ps->o.focus_blacklist))) {
|
||||
log_error("Post-processing of conditionals failed, some of your rules "
|
||||
"might not work");
|
||||
|
@ -2295,6 +2298,7 @@ static void session_destroy(session_t *ps) {
|
|||
free_wincondlst(&ps->o.paint_blacklist);
|
||||
free_wincondlst(&ps->o.unredir_if_possible_blacklist);
|
||||
free_wincondlst(&ps->o.rounded_corners_blacklist);
|
||||
free_wincondlst(&ps->o.round_borders_blacklist);
|
||||
|
||||
// Free tracked atom list
|
||||
{
|
||||
|
|
24
src/render.c
24
src/render.c
|
@ -395,13 +395,14 @@ static inline bool paint_isvalid(session_t *ps, const paint_t *ppaint) {
|
|||
*
|
||||
*/
|
||||
static inline void
|
||||
win_round_corners(session_t *ps, struct managed_win *w, const glx_texture_t *ptex,
|
||||
int shader_idx, float cr, xcb_render_picture_t tgt_buffer attr_unused,
|
||||
const region_t *reg_paint) {
|
||||
win_round_corners(session_t *ps, struct managed_win *w attr_unused, float cr attr_unused,
|
||||
xcb_render_picture_t tgt_buffer attr_unused, const region_t *reg_paint) {
|
||||
#ifdef CONFIG_OPENGL
|
||||
const int16_t x = w->g.x;
|
||||
const int16_t y = w->g.y;
|
||||
const auto wid = to_u16_checked(w->widthb);
|
||||
const auto hei = to_u16_checked(w->heightb);
|
||||
#endif
|
||||
|
||||
// log_debug("x:%d y:%d w:%d h:%d", x, y, wid, hei);
|
||||
|
||||
|
@ -412,15 +413,9 @@ win_round_corners(session_t *ps, struct managed_win *w, const glx_texture_t *pte
|
|||
} break;
|
||||
#ifdef CONFIG_OPENGL
|
||||
case BKEND_GLX:
|
||||
if (shader_idx == 1) {
|
||||
glx_round_corners_dst1(ps, w, ptex, shader_idx, x, y, wid, hei,
|
||||
(float)ps->psglx->z - 0.5f, cr, reg_paint,
|
||||
&w->glx_round_cache);
|
||||
} else {
|
||||
glx_round_corners_dst0(ps, w, ptex, shader_idx, x, y, wid, hei,
|
||||
(float)ps->psglx->z - 0.5f, cr, reg_paint,
|
||||
&w->glx_round_cache);
|
||||
}
|
||||
glx_round_corners_dst(ps, w, w->glx_texture_bg, x, y, wid, hei,
|
||||
(float)ps->psglx->z - 0.5f, cr, reg_paint,
|
||||
&w->glx_round_cache);
|
||||
break;
|
||||
#endif
|
||||
default: assert(0);
|
||||
|
@ -1154,6 +1149,7 @@ void paint_all(session_t *ps, struct managed_win *t, bool ignore_damage) {
|
|||
if (pixman_region32_not_empty(®_tmp)) {
|
||||
set_tgt_clip(ps, ®_tmp);
|
||||
|
||||
#ifdef CONFIG_OPENGL
|
||||
// If rounded corners backup the region first
|
||||
if (w->corner_radius > 0) {
|
||||
const int16_t x = w->g.x;
|
||||
|
@ -1162,6 +1158,7 @@ void paint_all(session_t *ps, struct managed_win *t, bool ignore_damage) {
|
|||
const auto hei = to_u16_checked(w->heightb);
|
||||
glx_bind_texture(ps, &w->glx_texture_bg, x, y, wid, hei, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Blur window background
|
||||
if (w->blur_background &&
|
||||
|
@ -1175,8 +1172,7 @@ void paint_all(session_t *ps, struct managed_win *t, bool ignore_damage) {
|
|||
|
||||
// Round window corners
|
||||
if (w->corner_radius > 0) {
|
||||
win_round_corners(ps, w, w->glx_texture_bg, 0,
|
||||
(float)w->corner_radius,
|
||||
win_round_corners(ps, w, (float)w->corner_radius,
|
||||
ps->tgt_buffer.pict, ®_tmp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1090,6 +1090,11 @@ static void win_determine_rounded_corners(session_t *ps, struct managed_win *w)
|
|||
// w->border_col = { -1., -1, -1, -1 };
|
||||
w->border_col[0] = w->border_col[1] = w->border_col[2] =
|
||||
w->border_col[3] = -1.0;
|
||||
if (w && c2_match(ps, w, ps->o.round_borders_blacklist, NULL)) {
|
||||
w->round_borders = 0;
|
||||
} else {
|
||||
w->round_borders = ps->o.round_borders;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -220,6 +220,7 @@ struct managed_win {
|
|||
|
||||
/// Radius of rounded window corners
|
||||
int corner_radius;
|
||||
bool round_borders;
|
||||
float border_col[4];
|
||||
|
||||
// Fading-related members
|
||||
|
|
Loading…
Add table
Reference in a new issue