Merge remote-tracking branch 'yshui/next' into next

This commit is contained in:
Arda Atci
2023-12-19 13:07:09 +03:00
19 changed files with 207 additions and 76 deletions

80
flake.lock generated Normal file
View File

@@ -0,0 +1,80 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1689068808,
"narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"git-ignore-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1660459072,
"narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"ref": "master",
"repo": "gitignore.nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1691186842,
"narHash": "sha256-wxBVCvZUwq+XS4N4t9NqsHV4E64cPVqQ2fdDISpjcw0=",
"path": "/nix/store/d42v5grfq77vr10r336kks0qjp0wij8d-source",
"rev": "18036c0be90f4e308ae3ebcab0e14aae0336fe42",
"type": "path"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"git-ignore-nix": "git-ignore-nix",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

34
flake.nix Normal file
View File

@@ -0,0 +1,34 @@
{
inputs = {
flake-utils.url = github:numtide/flake-utils;
git-ignore-nix = {
url = github:hercules-ci/gitignore.nix/master;
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self, flake-utils, nixpkgs, git-ignore-nix, ...
}: flake-utils.lib.eachDefaultSystem (system: let
overlay = self: super: {
picom = super.picom.overrideAttrs (oldAttrs: rec {
pname = "picom";
buildInputs = [
self.pcre2 self.xorg.xcbutil
] ++ self.lib.remove self.xorg.libXinerama (
self.lib.remove self.pcre oldAttrs.buildInputs
);
src = git-ignore-nix.lib.gitignoreSource ./.;
});
};
pkgs = import nixpkgs { inherit system overlays; config.allowBroken = true; };
overlays = [ overlay ];
in rec {
inherit overlay overlays;
defaultPackage = pkgs.picom;
devShell = defaultPackage.overrideAttrs {
buildInputs = defaultPackage.buildInputs ++ [
pkgs.clang-tools
];
};
});
}

View File

@@ -119,11 +119,7 @@ struct backend_operations {
// =========== Initialization ===========
/// Initialize the backend, prepare for rendering to the target window.
/// Here is how you should choose target window:
/// 1) if ps->overlay is not XCB_NONE, use that
/// 2) use ps->root otherwise
// TODO(yshui) make the target window a parameter
backend_t *(*init)(session_t *)attr_nonnull(1);
backend_t *(*init)(session_t *, xcb_window_t)attr_nonnull(1);
void (*deinit)(backend_t *backend_data) attr_nonnull(1);
/// Called when rendering will be stopped for an unknown amount of
@@ -220,18 +216,18 @@ struct backend_operations {
struct xvisual_info fmt, bool owned);
/// Create a shadow context for rendering shadows with radius `radius`.
/// Default implementation: default_backend_create_shadow_context
/// Default implementation: default_create_shadow_context
struct backend_shadow_context *(*create_shadow_context)(backend_t *backend_data,
double radius);
/// Destroy a shadow context
/// Default implementation: default_backend_destroy_shadow_context
/// Default implementation: default_destroy_shadow_context
void (*destroy_shadow_context)(backend_t *backend_data,
struct backend_shadow_context *ctx);
/// Create a shadow image based on the parameters. Resulting image should have a
/// size of `width + radisu * 2` x `height + radius * 2`. Radius is set when the
/// shadow context is created.
/// Default implementation: default_backend_render_shadow
/// Default implementation: default_render_shadow
///
/// Required.
void *(*render_shadow)(backend_t *backend_data, int width, int height,

View File

@@ -293,8 +293,8 @@ shadow_picture_err:
return false;
}
void *default_backend_render_shadow(backend_t *backend_data, int width, int height,
struct backend_shadow_context *sctx, struct color color) {
void *default_render_shadow(backend_t *backend_data, int width, int height,
struct backend_shadow_context *sctx, struct color color) {
const conv *kernel = (void *)sctx;
xcb_render_picture_t shadow_pixel =
solid_picture(backend_data->c, true, 1, color.red, color.green, color.blue);

View File

@@ -54,16 +54,8 @@ solid_picture(struct x_connection *, bool argb, double a, double r, double g, do
xcb_image_t *make_shadow(struct x_connection *c, const conv *kernel, double opacity,
int width, int height);
/// The default implementation of `is_win_transparent`, it simply looks at win::mode. So
/// this is not suitable for backends that alter the content of windows
bool default_is_win_transparent(void *, win *, void *);
/// The default implementation of `is_frame_transparent`, it uses win::frame_opacity. Same
/// caveat as `default_is_win_transparent` applies.
bool default_is_frame_transparent(void *, win *, void *);
void *default_backend_render_shadow(backend_t *backend_data, int width, int height,
struct backend_shadow_context *sctx, struct color color);
void *default_render_shadow(backend_t *backend_data, int width, int height,
struct backend_shadow_context *sctx, struct color color);
/// Implement `render_shadow` with `shadow_from_mask`.
void *

View File

@@ -28,7 +28,7 @@ struct dummy_data {
struct backend_image mask;
};
struct backend_base *dummy_init(struct session *ps attr_unused) {
struct backend_base *dummy_init(session_t *ps attr_unused, xcb_window_t target attr_unused) {
auto ret = (struct backend_base *)ccalloc(1, struct dummy_data);
ret->c = &ps->c;
ret->loop = ps->loop;
@@ -184,7 +184,7 @@ struct backend_operations dummy_ops = {
.bind_pixmap = dummy_bind_pixmap,
.create_shadow_context = default_create_shadow_context,
.destroy_shadow_context = default_destroy_shadow_context,
.render_shadow = default_backend_render_shadow,
.render_shadow = default_render_shadow,
.make_mask = dummy_make_mask,
.release_image = dummy_release_image,
.is_image_transparent = dummy_is_image_transparent,

View File

@@ -130,7 +130,7 @@ static bool egl_set_swap_interval(int interval, EGLDisplay dpy) {
/**
* Initialize OpenGL.
*/
static backend_t *egl_init(session_t *ps) {
static backend_t *egl_init(session_t *ps, xcb_window_t target) {
bool success = false;
struct egl_data *gd = NULL;
@@ -211,8 +211,8 @@ static backend_t *egl_init(session_t *ps) {
}
// clang-format on
gd->target_win = eglCreatePlatformWindowSurfaceProc(
gd->display, config, (xcb_window_t[]){session_get_target_window(ps)}, NULL);
gd->target_win =
eglCreatePlatformWindowSurfaceProc(gd->display, config, &target, NULL);
if (gd->target_win == EGL_NO_SURFACE) {
log_error("Failed to create EGL surface.");
goto end;

View File

@@ -1356,8 +1356,11 @@ void *gl_shadow_from_mask(backend_t *base, void *mask,
glBindTexture(GL_TEXTURE_2D, tmp_texture);
glUseProgram(gd->shadow_shader.prog);
glUniform4f(gd->shadow_shader.uniform_color, (GLfloat)color.red,
(GLfloat)color.green, (GLfloat)color.blue, (GLfloat)color.alpha);
// The shadow color is converted to the premultiplied format to respect the
// globally set glBlendFunc and thus get the correct and expected result.
glUniform4f(gd->shadow_shader.uniform_color, (GLfloat)(color.red * color.alpha),
(GLfloat)(color.green * color.alpha),
(GLfloat)(color.blue * color.alpha), (GLfloat)color.alpha);
// clang-format off
GLuint indices[] = {0, 1, 2, 2, 3, 0};

View File

@@ -227,13 +227,13 @@ static bool glx_set_swap_interval(int interval, Display *dpy, GLXDrawable drawab
/**
* Initialize OpenGL.
*/
static backend_t *glx_init(session_t *ps) {
static backend_t *glx_init(session_t *ps, xcb_window_t target) {
bool success = false;
glxext_init(ps->c.dpy, ps->c.screen);
auto gd = ccalloc(1, struct _glx_data);
init_backend_base(&gd->gl.base, ps);
gd->target_win = session_get_target_window(ps);
gd->target_win = target;
XVisualInfo *pvis = NULL;
@@ -371,12 +371,12 @@ glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b
if (fmt.visual_depth > OPENGL_MAX_DEPTH) {
log_error("Requested depth %d higher than max possible depth %d.",
fmt.visual_depth, OPENGL_MAX_DEPTH);
return false;
return NULL;
}
if (fmt.visual_depth < 0) {
log_error("Pixmap %#010x with invalid depth %d", pixmap, fmt.visual_depth);
return false;
return NULL;
}
auto r =

View File

@@ -176,8 +176,8 @@ static xcb_render_picture_t process_mask(struct _xrender_data *xd, struct xrende
*allocated = false;
return inner->pict;
}
const auto tmpw = to_u16_checked(inner->width);
const auto tmph = to_u16_checked(inner->height);
auto const tmpw = to_u16_checked(inner->width);
auto const tmph = to_u16_checked(inner->height);
*allocated = true;
x_clear_picture_clip_region(xd->base.c, inner->pict);
auto ret = x_create_picture_with_visual(
@@ -226,13 +226,13 @@ compose_impl(struct _xrender_data *xd, struct xrender_image *xrimg, coord_t dst,
region_t reg;
bool has_alpha = inner->has_alpha || img->opacity != 1;
const auto tmpw = to_u16_checked(inner->width);
const auto tmph = to_u16_checked(inner->height);
const auto tmpew = to_u16_checked(img->ewidth);
const auto tmpeh = to_u16_checked(img->eheight);
auto const tmpw = to_u16_checked(inner->width);
auto const tmph = to_u16_checked(inner->height);
auto const tmpew = to_u16_checked(img->ewidth);
auto const tmpeh = to_u16_checked(img->eheight);
// Remember: the mask has a 1-pixel border
const auto mask_dst_x = to_i16_checked(dst.x - mask_dst.x + 1);
const auto mask_dst_y = to_i16_checked(dst.y - mask_dst.y + 1);
auto const mask_dst_x = to_i16_checked(dst.x - mask_dst.x + 1);
auto const mask_dst_y = to_i16_checked(dst.y - mask_dst.y + 1);
const xcb_render_color_t dim_color = {
.red = 0, .green = 0, .blue = 0, .alpha = (uint16_t)(0xffff * img->dim)};
@@ -250,10 +250,16 @@ compose_impl(struct _xrender_data *xd, struct xrender_image *xrimg, coord_t dst,
}
if (((img->color_inverted || img->dim != 0) && has_alpha) || img->corner_radius != 0) {
// Apply image properties using a temporary image, because the source
// image is transparent. Otherwise the properties can be applied directly
// on the target image.
// image is transparent or will get transparent corners. Otherwise the
// properties can be applied directly on the target image.
// Also force a 32-bit ARGB visual for transparent corners, otherwise the
// corners become black.
auto visual =
(img->corner_radius != 0 && inner->depth != 32)
? x_get_visual_for_standard(xd->base.c, XCB_PICT_STANDARD_ARGB_32)
: inner->visual;
auto tmp_pict = x_create_picture_with_visual(
xd->base.c, inner->width, inner->height, inner->visual, 0, NULL);
xd->base.c, inner->width, inner->height, visual, 0, NULL);
// Set clip region translated to source coordinate
x_set_picture_clip_region(xd->base.c, tmp_pict, to_i16_checked(-dst.x),
@@ -395,8 +401,8 @@ static bool blur(backend_t *backend_data, double opacity, void *ctx_, void *mask
resize_region(&reg_op, bctx->resize_width, bctx->resize_height);
const pixman_box32_t *extent_resized = pixman_region32_extents(&reg_op_resized);
const auto height_resized = to_u16_checked(extent_resized->y2 - extent_resized->y1);
const auto width_resized = to_u16_checked(extent_resized->x2 - extent_resized->x1);
auto const height_resized = to_u16_checked(extent_resized->y2 - extent_resized->y1);
auto const width_resized = to_u16_checked(extent_resized->x2 - extent_resized->x1);
static const char *filter0 = "Nearest"; // The "null" filter
static const char *filter = "convolution";
@@ -872,7 +878,7 @@ static void get_blur_size(void *blur_context, int *width, int *height) {
*height = ctx->resize_height;
}
static backend_t *backend_xrender_init(session_t *ps) {
static backend_t *backend_xrender_init(session_t *ps, xcb_window_t target) {
if (ps->o.dithered_present) {
log_warn("\"dithered-present\" is not supported by the xrender backend.");
}
@@ -891,7 +897,7 @@ static backend_t *backend_xrender_init(session_t *ps) {
xd->black_pixel = solid_picture(&ps->c, true, 1, 0, 0, 0);
xd->white_pixel = solid_picture(&ps->c, true, 1, 1, 1, 1);
xd->target_win = session_get_target_window(ps);
xd->target_win = target;
xcb_render_create_picture_value_list_t pa = {
.subwindowmode = XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS,
};
@@ -984,10 +990,8 @@ struct backend_operations xrender_ops = {
.release_image = release_image,
.create_shadow_context = default_create_shadow_context,
.destroy_shadow_context = default_destroy_shadow_context,
.render_shadow = default_backend_render_shadow,
.render_shadow = default_render_shadow,
.make_mask = make_mask,
//.prepare_win = prepare_win,
//.release_win = release_win,
.is_image_transparent = default_is_image_transparent,
.buffer_age = buffer_age,
.max_buffer_age = 2,

View File

@@ -1336,7 +1336,7 @@ static xcb_atom_t c2_get_atom_type(const c2_l_t *pleaf) {
case C2_L_TDRAWABLE: return XCB_ATOM_DRAWABLE;
default: assert(0); break;
}
unreachable;
unreachable();
}
/**

View File

@@ -7,7 +7,9 @@
#endif
// clang-format off
#if __STDC_VERSION__ <= 201710L
#define auto __auto_type
#endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define likely_if(x) if (likely(x))
@@ -101,10 +103,12 @@
# endif
#endif
#if defined(__GNUC__) || defined(__clang__)
# define unreachable __builtin_unreachable()
#else
# define unreachable do {} while(0)
#ifndef unreachable
# if defined(__GNUC__) || defined(__clang__)
# define unreachable() __builtin_unreachable()
# else
# define unreachable() do {} while(0)
# endif
#endif
#ifndef __has_include

View File

@@ -39,7 +39,7 @@ void print_diagnostics(session_t *ps, const char *config_file, bool compositor_r
for (int i = 0; i < NUM_BKEND; i++) {
if (backend_list[i] && backend_list[i]->diagnostics) {
printf("\n### Backend: %s\n\n", BACKEND_STRS[i]);
auto data = backend_list[i]->init(ps);
auto data = backend_list[i]->init(ps, session_get_target_window(ps));
if (!data) {
printf(" Cannot initialize this backend\n");
} else {

View File

@@ -68,6 +68,7 @@ log_default_writev(struct log_target *tgt, const struct iovec *vec, int vcnt) {
static attr_const const char *log_level_to_string(enum log_level level) {
switch (level) {
case LOG_LEVEL_TRACE: return "TRACE";
case LOG_LEVEL_VERBOSE: return "VERBOSE";
case LOG_LEVEL_DEBUG: return "DEBUG";
case LOG_LEVEL_INFO: return "INFO";
case LOG_LEVEL_WARN: return "WARN";
@@ -81,6 +82,9 @@ enum log_level string_to_log_level(const char *str) {
if (strcasecmp(str, "TRACE") == 0) {
return LOG_LEVEL_TRACE;
}
if (strcasecmp(str, "VERBOSE") == 0) {
return LOG_LEVEL_VERBOSE;
}
if (strcasecmp(str, "DEBUG") == 0) {
return LOG_LEVEL_DEBUG;
}
@@ -234,12 +238,10 @@ struct log_target *null_logger_new(void) {
static void null_logger_write(struct log_target *tgt attr_unused,
const char *str attr_unused, size_t len attr_unused) {
return;
}
static void null_logger_writev(struct log_target *tgt attr_unused,
const struct iovec *vec attr_unused, int vcnt attr_unused) {
return;
}
static const struct log_ops null_logger_ops = {
@@ -275,6 +277,7 @@ static void file_logger_destroy(struct log_target *tgt) {
static const char *terminal_colorize_begin(enum log_level level) {
switch (level) {
case LOG_LEVEL_TRACE: return ANSI("30;2");
case LOG_LEVEL_VERBOSE:
case LOG_LEVEL_DEBUG: return ANSI("37;2");
case LOG_LEVEL_INFO: return ANSI("92");
case LOG_LEVEL_WARN: return ANSI("33");

View File

@@ -9,11 +9,19 @@
enum log_level {
LOG_LEVEL_INVALID = -1,
/// Very noisy debug messages, many lines per frame.
LOG_LEVEL_TRACE = 0,
/// Frequent debug messages, a few lines per frame.
LOG_LEVEL_VERBOSE,
/// Less frequent debug messages.
LOG_LEVEL_DEBUG,
/// Informational messages.
LOG_LEVEL_INFO,
/// Warnings.
LOG_LEVEL_WARN,
/// Errors.
LOG_LEVEL_ERROR,
/// Fatal errors.
LOG_LEVEL_FATAL,
};
@@ -31,6 +39,7 @@ enum log_level {
} \
} while (0)
#define log_trace(x, ...) LOG_UNLIKELY(TRACE, x, ##__VA_ARGS__)
#define log_verbose(x, ...) LOG_UNLIKELY(VERBOSE, x, ##__VA_ARGS__)
#define log_debug(x, ...) LOG_UNLIKELY(DEBUG, x, ##__VA_ARGS__)
#define log_info(x, ...) LOG(INFO, x, ##__VA_ARGS__)
#define log_warn(x, ...) LOG(WARN, x, ##__VA_ARGS__)

View File

@@ -265,7 +265,7 @@ void schedule_render(session_t *ps, bool triggered_by_vblank) {
goto schedule;
}
const auto deadline = ps->last_msc_instant + (unsigned long)divisor * frame_time;
auto const deadline = ps->last_msc_instant + (unsigned long)divisor * frame_time;
unsigned int available = 0;
if (deadline > now_us) {
available = (unsigned int)(deadline - now_us);
@@ -605,7 +605,8 @@ static bool initialize_backend(session_t *ps) {
assert(!ps->backend_data);
// Reinitialize win_data
assert(backend_list[ps->o.backend]);
ps->backend_data = backend_list[ps->o.backend]->init(ps);
ps->backend_data =
backend_list[ps->o.backend]->init(ps, session_get_target_window(ps));
if (!ps->backend_data) {
log_fatal("Failed to initialize backend, aborting...");
quit(ps);
@@ -770,6 +771,11 @@ static void handle_root_flags(session_t *ps) {
static struct managed_win *
paint_preprocess(session_t *ps, bool *fade_running, bool *animation_running) {
/**
* Go through the window stack and calculate some parameters for rendering.
*
* @return whether the operation succeeded
*/
// XXX need better, more general name for `fade_running`. It really
// means if fade is still ongoing after the current frame is rendered.
// Same goes for `animation_running`.
@@ -1209,7 +1215,7 @@ paint_preprocess(session_t *ps, bool *fade_running, bool *animation_running) {
ev_timer_stop(ps->loop, &ps->unredir_timer);
if (!ps->redirected) {
if (!redirect_start(ps)) {
return NULL;
return false;
}
}
}
@@ -1331,7 +1337,7 @@ static int register_cm(session_t *ps) {
// Set WM_CLIENT_MACHINE. As per EWMH, because we set _NET_WM_PID, we must also
// set WM_CLIENT_MACHINE.
{
const auto hostname_max = (unsigned long)sysconf(_SC_HOST_NAME_MAX);
auto const hostname_max = (unsigned long)sysconf(_SC_HOST_NAME_MAX);
char *hostname = malloc(hostname_max);
if (gethostname(hostname, hostname_max) == 0) {

View File

@@ -474,10 +474,10 @@ void paint_one(session_t *ps, struct managed_win *w, const region_t *reg_paint)
} else {
// Painting parameters
const margin_t extents = win_calc_frame_extents(w);
const auto t = extents.top;
const auto l = extents.left;
const auto b = extents.bottom;
const auto r = extents.right;
auto const t = extents.top;
auto const l = extents.left;
auto const b = extents.bottom;
auto const r = extents.right;
#define COMP_BDR(cx, cy, cwid, chei) \
paint_region(ps, w, (cx), (cy), (cwid), (chei), w->frame_opacity * w->opacity, \
@@ -888,8 +888,8 @@ win_blur_background(session_t *ps, struct managed_win *w, xcb_render_picture_t t
const region_t *reg_paint) {
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);
auto const wid = to_u16_checked(w->widthb);
auto const hei = to_u16_checked(w->heightb);
const int cr = w ? w->corner_radius : 0;
double factor_center = 1.0;
@@ -1174,8 +1174,8 @@ void paint_all(session_t *ps, struct managed_win *t) {
if (w->corner_radius > 0 && ps->o.backend == BKEND_GLX) {
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);
auto const wid = to_u16_checked(w->widthb);
auto const hei = to_u16_checked(w->heightb);
glx_bind_texture(ps, &w->glx_texture_bg, x, y, wid, hei);
}
#endif
@@ -1195,8 +1195,8 @@ void paint_all(session_t *ps, struct managed_win *t) {
// Rounded corners for XRender is implemented inside render()
// Round window corners
if (w->corner_radius > 0 && ps->o.backend == BKEND_GLX) {
const auto wid = to_u16_checked(w->widthb);
const auto hei = to_u16_checked(w->heightb);
auto const wid = to_u16_checked(w->widthb);
auto const hei = to_u16_checked(w->heightb);
glx_round_corners_dst(ps, w, w->glx_texture_bg, w->g.x,
w->g.y, wid, hei,
(float)ps->psglx->z - 0.5F,

View File

@@ -30,7 +30,7 @@ void report_allocation_failure(const char *func, const char *file, unsigned int
ssize_t _ attr_unused = writev(STDERR_FILENO, v, ARR_SIZE(v));
abort();
unreachable;
unreachable();
}
///

View File

@@ -2744,7 +2744,7 @@ bool win_check_fade_finished(session_t *ps, struct managed_win *w) {
case WSTATE_DESTROYING: destroy_win_finish(ps, &w->base); return true;
case WSTATE_MAPPING: map_win_finish(w); return false;
case WSTATE_FADING: w->state = WSTATE_MAPPED; break;
default: unreachable;
default: unreachable();
}
}
@@ -3071,7 +3071,7 @@ void win_clear_flags(struct managed_win *w, uint64_t flags) {
}
void win_set_properties_stale(struct managed_win *w, const xcb_atom_t *props, int nprops) {
const auto bits_per_element = sizeof(*w->stale_props) * 8;
auto const bits_per_element = sizeof(*w->stale_props) * 8;
size_t new_capacity = w->stale_props_capacity;
// Calculate the new capacity of the properties array
@@ -3106,12 +3106,12 @@ static void win_clear_all_properties_stale(struct managed_win *w) {
}
static bool win_fetch_and_unset_property_stale(struct managed_win *w, xcb_atom_t prop) {
const auto bits_per_element = sizeof(*w->stale_props) * 8;
auto const bits_per_element = sizeof(*w->stale_props) * 8;
if (prop >= w->stale_props_capacity * bits_per_element) {
return false;
}
const auto mask = 1UL << (prop % bits_per_element);
auto const mask = 1UL << (prop % bits_per_element);
bool ret = w->stale_props[prop / bits_per_element] & mask;
w->stale_props[prop / bits_per_element] &= ~mask;
return ret;