1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2025-01-29 01:58:26 +00:00

Remove _member_access from geometry (#1910)

* It was difficult/too costly ensuring temporary this was correct when vecs contained in rects were accessed directly.
* Added semantics to `rect` and some utility functions.

Signed-off-by: Tin Švagelj <tin.svagelj@live.com>
This commit is contained in:
Tin Švagelj 2024-05-13 22:08:27 +02:00 committed by GitHub
parent 968fc7fcbc
commit 2d50767216
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 1491 additions and 1417 deletions

View File

@ -51,7 +51,10 @@ if(MAINTAINER_MODE)
endif(MAINTAINER_MODE)
# Always use libc++ when compiling w/ clang
add_compile_options($<$<COMPILE_LANG_AND_ID:CXX,Clang>:-stdlib=libc++>)
add_compile_options(
$<$<COMPILE_LANG_AND_ID:CXX,Clang>:-stdlib=libc++>
$<$<COMPILE_LANG_AND_ID:CXX,Clang>:-Wno-unknown-warning-option>
$<$<COMPILE_LANG_AND_ID:CXX,GCC>:-Wno-unknown-warning>)
add_link_options($<$<COMPILE_LANG_AND_ID:CXX,Clang>:-stdlib=libc++>)
option(CHECK_CODE_QUALITY "Check code formatting/quality with clang" false)

File diff suppressed because it is too large Load Diff

View File

@ -303,10 +303,10 @@ static void output_geometry(void *data, struct wl_output *wl_output, int32_t x,
// Maybe also support (if XDG protocol not reported):
// - kde-output-management(-v2)
// - wlr-output-management-unstable-v1
workarea.x = x; // TODO: use xdg_output.logical_position
workarea.y = y;
workarea.width = physical_width;
workarea.height = physical_height;
workarea = absolute_rect<int>(
vec2i(x, y),
vec2i(x + physical_width,
y + physical_height)); // TODO: use xdg_output.logical_position
}
static void output_mode(void *data, struct wl_output *wl_output, uint32_t flags,
@ -413,8 +413,8 @@ void window_get_width_height(struct window *window, int *w, int *h);
void window_layer_surface_set_size(struct window *window) {
zwlr_layer_surface_v1_set_size(global_window->layer_surface,
global_window->rectangle.width,
global_window->rectangle.height);
global_window->rectangle.width(),
global_window->rectangle.height());
}
#ifdef BUILD_MOUSE_EVENTS
@ -428,7 +428,7 @@ static void on_pointer_enter(void *data, wl_pointer *pointer,
auto pos =
vec2d(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y));
last_known_positions[pointer] = pos;
auto pos_abs = w->rectangle.pos + pos;
auto pos_abs = w->rectangle.pos() + pos;
mouse_crossing_event event{mouse_event_t::AREA_ENTER, pos, pos_abs};
llua_mouse_hook(event);
@ -439,7 +439,7 @@ static void on_pointer_leave(void *data, struct wl_pointer *pointer,
auto w = reinterpret_cast<struct window *>(data);
auto pos = last_known_positions[pointer];
auto pos_abs = w->rectangle.pos + pos;
auto pos_abs = w->rectangle.pos() + pos;
mouse_crossing_event event{mouse_event_t::AREA_LEAVE, pos, pos_abs};
llua_mouse_hook(event);
@ -453,7 +453,7 @@ static void on_pointer_motion(void *data, struct wl_pointer *pointer,
auto pos =
vec2d(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y));
last_known_positions[pointer] = pos;
auto pos_abs = w->rectangle.pos + pos;
auto pos_abs = w->rectangle.pos() + pos;
mouse_move_event event{pos, pos_abs};
llua_mouse_hook(event);
@ -465,7 +465,7 @@ static void on_pointer_button(void *data, struct wl_pointer *pointer,
auto w = reinterpret_cast<struct window *>(data);
auto pos = last_known_positions[pointer];
auto pos_abs = w->rectangle.pos + pos;
auto pos_abs = w->rectangle.pos() + pos;
mouse_button_event event{
mouse_event_t::RELEASE,
@ -494,7 +494,7 @@ void on_pointer_axis(void *data, struct wl_pointer *pointer, std::uint32_t time,
auto w = reinterpret_cast<struct window *>(data);
auto pos = last_known_positions[pointer];
auto pos_abs = w->rectangle.pos + pos;
auto pos_abs = w->rectangle.pos() + pos;
mouse_scroll_event event{
pos,
@ -657,19 +657,19 @@ bool display_output_wayland::main_loop_wait(double t) {
/* resize window if it isn't right size */
if ((fixed_size == 0) &&
(text_size.x + 2 * border_total != width ||
text_size.y + 2 * border_total != height || scale_changed)) {
(text_size.x() + 2 * border_total != width ||
text_size.y() + 2 * border_total != height || scale_changed)) {
/* clamp text_width to configured maximum */
if (maximum_width.get(*state)) {
int mw = global_window->scale * maximum_width.get(*state);
if (text_size.x > mw && mw > 0) { text_size.x = mw; }
if (text_size.x() > mw && mw > 0) { text_size.set_x(mw); }
}
/* pending scale will be applied by resizing the window */
global_window->scale = global_window->pending_scale;
width = text_size.x + 2 * border_total;
height = text_size.y + 2 * border_total;
width = text_size.x() + 2 * border_total;
height = text_size.y() + 2 * border_total;
window_resize(global_window, width, height); /* resize window */
changed++;
@ -808,8 +808,8 @@ int display_output_wayland::calc_text_width(const char *s) {
}
static void adjust_coords(int &x, int &y) {
x -= text_start.x;
y -= text_start.y;
x -= text_start.x();
y -= text_start.y();
int border = get_border_total();
x += border;
y += border;
@ -1106,14 +1106,14 @@ static void shm_pool_destroy(struct shm_pool *pool) {
static int stride_for_shm_surface(rect<size_t> *rect, int scale) {
return cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
rect->width * scale);
rect->width() * scale);
}
static int data_length_for_shm_surface(rect<size_t> *rect, int scale) {
int stride;
stride = stride_for_shm_surface(rect, scale);
return stride * rect->height * scale;
return stride * rect->height() * scale;
}
static cairo_surface_t *create_shm_surface_from_pool(void *none,
@ -1142,9 +1142,9 @@ static cairo_surface_t *create_shm_surface_from_pool(void *none,
return NULL;
}
auto scaled = rectangle->size * scale;
auto scaled = rectangle->size() * scale;
surface = cairo_image_surface_create_for_data(
static_cast<unsigned char *>(map), cairo_format, scaled.x, scaled.y,
static_cast<unsigned char *>(map), cairo_format, scaled.x(), scaled.y(),
stride);
cairo_surface_set_user_data(surface, &shm_surface_data_key, data,
@ -1152,8 +1152,8 @@ static cairo_surface_t *create_shm_surface_from_pool(void *none,
format = WL_SHM_FORMAT_ARGB8888; /*or WL_SHM_FORMAT_RGB565*/
data->buffer = wl_shm_pool_create_buffer(pool->pool, offset, scaled.x,
scaled.y, stride, format);
data->buffer = wl_shm_pool_create_buffer(pool->pool, offset, scaled.x(),
scaled.y(), stride, format);
return surface;
}
@ -1195,8 +1195,8 @@ struct window *window_create(struct wl_surface *surface, struct wl_shm *shm,
struct window *window;
window = new struct window;
window->rectangle.pos = vec2<size_t>::Zero();
window->rectangle.size = vec2<size_t>(width, height);
window->rectangle.set_pos(vec2<size_t>::Zero());
window->rectangle.set_size(width, height);
window->scale = 0;
window->pending_scale = 1;
@ -1235,7 +1235,7 @@ void window_destroy(struct window *window) {
void window_resize(struct window *window, int width, int height) {
window_free_buffer(window);
window->rectangle.size = conky::vec2i(width, height);
window->rectangle.set_size(width, height);
window_allocate_buffer(window);
window_layer_surface_set_size(window);
}
@ -1248,14 +1248,15 @@ void window_commit_buffer(struct window *window) {
get_buffer_from_cairo_surface(window->cairo_surface), 0, 0);
/* repaint all the pixels in the surface, change size to only repaint changed
* area*/
wl_surface_damage(window->surface, window->rectangle.x, window->rectangle.y,
window->rectangle.width, window->rectangle.height);
wl_surface_damage(window->surface, window->rectangle.x(),
window->rectangle.y(), window->rectangle.width(),
window->rectangle.height());
wl_surface_commit(window->surface);
}
void window_get_width_height(struct window *window, int *w, int *h) {
*w = window->rectangle.width;
*h = window->rectangle.height;
*w = window->rectangle.width();
*h = window->rectangle.height();
}
} // namespace conky

View File

@ -184,7 +184,8 @@ static void X11_create_window() {
#ifdef OWN_WINDOW
if (own_window.get(*state)) {
if (fixed_pos == 0) {
XMoveWindow(display, window.window, window.geometry.x, window.geometry.y);
XMoveWindow(display, window.window, window.geometry.x(),
window.geometry.y());
}
set_transparent_background(window.window);
@ -278,7 +279,7 @@ bool display_output_x11::main_loop_wait(double t) {
vec2i border_total = vec2i::uniform(get_border_total());
if (need_to_update != 0) {
#ifdef OWN_WINDOW
auto old_pos = window.geometry.pos;
auto old_pos = window.geometry.pos();
#endif
need_to_update = 0;
@ -292,11 +293,11 @@ bool display_output_x11::main_loop_wait(double t) {
/* resize window if it isn't right size */
vec2<long> border_size = border_total * 2;
if ((fixed_size == 0) &&
(text_size + border_size != window.geometry.size)) {
window.geometry.size = text_size + border_size;
(text_size + border_size != window.geometry.size())) {
window.geometry.set_size(text_size + border_size);
draw_stuff(); /* redraw everything in our newly sized window */
XResizeWindow(display, window.window, window.geometry.width,
window.geometry.height); /* resize window */
XResizeWindow(display, window.window, window.geometry.width(),
window.geometry.height()); /* resize window */
set_transparent_background(window.window);
#ifdef BUILD_XDBE
/* swap buffers */
@ -305,8 +306,8 @@ bool display_output_x11::main_loop_wait(double t) {
if (use_xpmdb.get(*state)) {
XFreePixmap(display, window.back_buffer);
window.back_buffer = XCreatePixmap(
display, window.window, window.geometry.width,
window.geometry.height, DefaultDepth(display, screen));
display, window.window, window.geometry.width(),
window.geometry.height(), DefaultDepth(display, screen));
if (window.back_buffer != None) {
window.drawable = window.back_buffer;
@ -316,7 +317,7 @@ bool display_output_x11::main_loop_wait(double t) {
}
XSetForeground(display, window.gc, 0);
XFillRectangle(display, window.drawable, window.gc, 0, 0,
window.geometry.width, window.geometry.height);
window.geometry.width(), window.geometry.height());
}
#endif
@ -326,9 +327,9 @@ bool display_output_x11::main_loop_wait(double t) {
}
/* move window if it isn't in right position */
if ((fixed_pos == 0) && old_pos != window.geometry.pos) {
XMoveWindow(display, window.window, window.geometry.x,
window.geometry.y);
if ((fixed_pos == 0) && old_pos != window.geometry.pos()) {
XMoveWindow(display, window.window, window.geometry.x(),
window.geometry.y());
changed++;
}
@ -347,11 +348,9 @@ bool display_output_x11::main_loop_wait(double t) {
#else
if (use_xpmdb.get(*state)) {
#endif
conky::rect<int> r(text_start, text_size);
r.pos -= border_total;
r.size += border_total * 2;
XRectangle rect = r.to_xrectangle();
XRectangle rect = conky::rect<int>(text_start - border_total,
text_size + border_total * 2)
.to_xrectangle();
XUnionRectWithRegion(&rect, x11_stuff.region, x11_stuff.region);
}
}
@ -378,11 +377,9 @@ bool display_output_x11::main_loop_wait(double t) {
#else
if (use_xpmdb.get(*state)) {
#endif
conky::rect<int> r(text_start, text_size);
r.pos -= border_total;
r.size += border_total * 2;
XRectangle rect = r.to_xrectangle();
XRectangle rect = conky::rect<int>(text_start - border_total,
text_size + border_total * 2)
.to_xrectangle();
XUnionRectWithRegion(&rect, x11_stuff.region, x11_stuff.region);
}
XSetRegion(display, window.gc, x11_stuff.region);
@ -507,13 +504,13 @@ bool handle_event<x_event_handler::MOUSE_INPUT>(
if (!cursor_inside) {
*consumed = llua_mouse_hook(mouse_crossing_event(
mouse_event_t::AREA_ENTER,
data->pos_absolute - window.geometry.pos, data->pos_absolute));
data->pos_absolute - window.geometry.pos(), data->pos_absolute));
}
cursor_inside = true;
} else if (cursor_inside) {
*consumed = llua_mouse_hook(mouse_crossing_event(
mouse_event_t::AREA_LEAVE, data->pos_absolute - window.geometry.pos,
data->pos_absolute));
mouse_event_t::AREA_LEAVE,
data->pos_absolute - window.geometry.pos(), data->pos_absolute));
cursor_inside = false;
}
@ -650,8 +647,8 @@ bool handle_event<x_event_handler::CONFIGURE>(
if (own_window.get(*state)) {
auto configure_size = vec2i(ev.xconfigure.width, ev.xconfigure.height);
/* if window size isn't what's expected, set fixed size */
if (configure_size != window.geometry.size) {
if (window.geometry.size.surface() != 0) { fixed_size = 1; }
if (configure_size != window.geometry.size()) {
if (window.geometry.size().surface() != 0) { fixed_size = 1; }
/* clear old stuff before screwing up
* size and pos */
@ -660,18 +657,16 @@ bool handle_event<x_event_handler::CONFIGURE>(
{
XWindowAttributes attrs;
if (XGetWindowAttributes(display, window.window, &attrs) != 0) {
window.geometry.size = vec2i(attrs.width, attrs.height);
window.geometry.set_size(attrs.width, attrs.height);
}
}
auto border_total = vec2i::uniform(get_border_total() * 2);
auto new_text_size = window.geometry.size - border_total;
text_size = new_text_size;
text_size = window.geometry.size() - border_total;
// don't apply dpi scaling to max pixel size
int mw = maximum_width.get(*state);
if (text_size.x > mw && mw > 0) { text_size.x = mw; }
if (text_size.x() > mw && mw > 0) { text_size.set_x(mw); }
}
/* if position isn't what expected, set fixed pos
@ -859,9 +854,9 @@ void display_output_x11::cleanup() {
if (window_created == 1) {
int border_total = get_border_total();
XClearArea(display, window.window, text_start.x - border_total,
text_start.y - border_total, text_size.x + 2 * border_total,
text_size.y + 2 * border_total, 0);
XClearArea(display, window.window, text_start.x() - border_total,
text_start.y() - border_total, text_size.x() + 2 * border_total,
text_size.y() + 2 * border_total, 0);
}
destroy_window();
free_fonts(utf8_mode.get(*state));
@ -963,7 +958,7 @@ void display_output_x11::draw_arc(int x, int y, int w, int h, int a1, int a2) {
void display_output_x11::move_win(int x, int y) {
#ifdef OWN_WINDOW
window.geometry.pos = vec2i(x, y);
window.geometry.set_pos(x, y);
XMoveWindow(display, window.window, x, y);
#endif /* OWN_WINDOW */
}
@ -1000,9 +995,9 @@ void display_output_x11::clear_text(int exposures) {
/* there is some extra space for borders and outlines */
int border_total = get_border_total();
XClearArea(display, window.window, text_start.x - border_total,
text_start.y - border_total, text_size.x + 2 * border_total,
text_size.y + 2 * border_total, exposures != 0 ? True : 0);
XClearArea(display, window.window, text_start.x() - border_total,
text_start.y() - border_total, text_size.x() + 2 * border_total,
text_size.y() + 2 * border_total, exposures != 0 ? True : 0);
}
}

View File

@ -10,6 +10,7 @@
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <limits>
#include <numeric>
#include <type_traits>
@ -22,60 +23,43 @@
namespace conky {
namespace _priv_geom {
/// @brief Member access wrapper for containers of values.
/// @brief Constructs an index assignable type from an array with different
/// value types using `static_cast`.
///
/// Emulates member access to abstract away the fact that components might not
/// be discrete `T` types.
/// Panics at runtime if `O` can be indexed by every value in range `0` to
/// (excluding) `Length`.
///
/// This is implementation detail for `geometry.h` and not intended to be used
/// elsewhere.
template <typename Container, typename T>
struct _member_access {
Container *value;
size_t index;
constexpr _member_access(Container *value, size_t index)
: value(value), index(index) {}
/// @brief Converts `_member_access` to `T`.
inline T operator*() const { return this->value->at(this->index); }
/// @brief Assignment handler for `new_value` to `T` at `index`.
inline const _member_access &operator=(T new_value) const {
this->value->set(this->index, new_value);
return *this;
/// @tparam Input source array element
/// @tparam R target element type
/// @tparam Output target container
/// @tparam Length array length
/// @param value array to pad/trim
/// @return casted array
template <typename Input, typename R, size_t Length, typename Output>
inline Output cast_to_assignable(const Input &value, Output &target) {
if constexpr (std::is_same_v<Input, Output>) { return value; }
for (size_t i = 0; i < Length; i++) {
target[i] = static_cast<R>(value.at(i));
}
return target;
}
#define ASSIGN_OP_IMPL(assign_op_name, application) \
inline T assign_op_name(T other) const { \
this->value->set(this->index, \
this->value->at(this->index) application other); \
return *this; \
}
ASSIGN_OP_IMPL(operator+=, +)
ASSIGN_OP_IMPL(operator-=, -)
ASSIGN_OP_IMPL(operator*=, *)
ASSIGN_OP_IMPL(operator/=, /)
#undef ASSIGN_OP_IMPL
/// @brief Converts `_member_access` to `T`.
inline operator T() const { return this->value->at(this->index); }
};
/// @brief Takes an array and pads/trims it to the desired length by inserting
/// zeros or discarding unwanted elements
/// @brief Constructs a casted array from an array with different value types
/// using `static_cast`.
///
/// @tparam T source array element
/// @tparam R target array element
/// @tparam Length array length
/// @param value array to pad/trim
/// @return padded/trimmed array
/// @return casted array
template <typename T, typename R, size_t Length>
std::array<R, Length> cast_array(std::array<T, Length> value) {
inline std::array<R, Length> cast_array(const std::array<T, Length> &value) {
static_assert(std::is_convertible_v<T, R>, "T is not convertible to R");
if constexpr (std::is_same_v<T, R>) { return value; }
std::array<R, Length> buff;
std::copy_n(value.begin(), Length, buff.begin());
return buff;
std::array<R, Length> result;
cast_to_assignable<std::array<T, Length>, R, Length, std::array<R, Length>>(
value, result);
return result;
}
/// @brief Takes an array and pads/trims it to the desired length by inserting
@ -86,39 +70,12 @@ std::array<R, Length> cast_array(std::array<T, Length> value) {
/// @param value array to pad/trim
/// @return padded/trimmed array
template <typename T, size_t Source, size_t Target>
std::array<T, Target> resize_array(std::array<T, Source> value) {
inline std::array<T, Target> resize_array(std::array<T, Source> value) {
if constexpr (Source == Target) { return value; }
auto buff = std::array<T, Target>{0};
std::copy_n(value.begin(), std::min(Source, Target), buff.begin());
return buff;
}
class _no_z_member {};
template <typename Of, typename T>
struct _has_z_member {
static_assert(std::is_arithmetic_v<T>,
"vector z member type (T) must be a number");
using ComponentRef = _member_access<Of, T>;
/// @brief vec z value.
///
/// Treat it as `T`. Use `*z` in case type coertion is needed.
const ComponentRef z = ComponentRef(this, 2);
};
class _no_w_member {};
template <typename Of, typename T>
struct _has_w_member {
static_assert(std::is_arithmetic_v<T>,
"vector w member type (T) must be a number");
using ComponentRef = _member_access<Of, T>;
/// @brief vec w value.
///
/// Treat it as `T`. Use `*w` in case type coertion is needed.
const ComponentRef w = ComponentRef(this, 3);
};
} // namespace _priv_geom
/// @brief A 2D vector representation.
@ -129,15 +86,7 @@ struct _has_w_member {
///
/// @tparam T numeric component type.
template <typename T, size_t Length>
struct vec
// conditionally add z member accessor
: public std::conditional_t<(Length >= 3),
_priv_geom::_has_z_member<vec<T, Length>, T>,
_priv_geom::_no_z_member>,
// conditionally add w member accessor
public std::conditional_t<(Length >= 4),
_priv_geom::_has_w_member<vec<T, Length>, T>,
_priv_geom::_no_w_member> {
struct vec {
static_assert(std::is_arithmetic_v<T>, "T must be a number");
static_assert(Length >= 2, "Length must be greater than 2");
@ -149,23 +98,19 @@ struct vec
class _disabled {};
protected:
using ComponentRef = _priv_geom::_member_access<vec<T, Length>, T>;
using Data = Vc::array<T, Length>;
Data value;
public:
vec() : value(Data{0}) {}
vec(Data value) : value(value) {}
vec(const Data &value) : value(value) {}
vec(std::array<T, Length> array) {
Vc::array<T, Length> vc_array;
for (size_t i = 0; i < Length; ++i) { vc_array[i] = array[i]; }
this->value = vc_array;
_priv_geom::cast_to_assignable<std::array<T, Length>, T, Length,
Vc::array<T, Length>>(array, this->value);
}
template <typename O = T>
vec(vec<O, Length> other)
: vec(_priv_geom::cast_array<O, T, Length>(other.to_array())) {}
vec(const vec<T, Length> &other) : vec(other.value) {}
vec(T x, T y) : vec<T, 2>(std::array<T, 2>{x, y}) {
static_assert(Length == 2, "constructor only valid for vec2<T>");
@ -177,16 +122,12 @@ struct vec
static_assert(Length == 4, "constructor only valid for vec4<T>");
}
vec(vec<T, Length> &&other) { this->value = other->value; }
static inline vec<T, Length> uniform(T x) {
return vec<T, Length>(std::array<T, Length>{x});
}
std::array<T, Length> to_array() const {
std::array<T, Length> result;
for (size_t i = 0; i < Length; ++i) { result[i] = this->value[i]; }
return result;
}
/// @brief Returns vec component at `index`.
/// @param index component index.
/// @return component at `index` of this vec.
@ -194,19 +135,19 @@ struct vec
/// @brief vec x component.
/// @return x value of this vec.
inline T get_x() const { return this->at(0); }
inline T x() const { return this->at(0); }
/// @brief vec y component.
/// @return y value of this vec.
inline T get_y() const { return this->at(1); }
inline T y() const { return this->at(1); }
/// @brief vec z component.
/// @return z value of this vec.
inline T get_z() const {
inline T z() const {
static_assert(Length >= 3, "vector doesn't have a z component");
return this->at(2);
}
/// @brief vec w component.
/// @return w value of this vec.
inline T get_w() const {
inline T w() const {
static_assert(Length >= 4, "vector doesn't have a w component");
return this->at(3);
}
@ -224,45 +165,21 @@ struct vec
this->set(3, new_value);
}
/// @brief vec x value.
///
/// Treat it as `T`. Use `*x` in case type coertion is needed.
const ComponentRef x = ComponentRef(this, 0);
/// @brief vec y value.
///
/// Treat it as `T`. Use `*y` in case type coertion is needed.
const ComponentRef y = ComponentRef(this, 1);
// z & w are conditionally defined by _has_z_member and _has_w_member in
// _priv_geom because member templates aren't allowed.
vec<T, Length> &operator=(vec<T, Length> other) {
vec<T, Length> &operator=(const vec<T, Length> &other) {
this->value = other.value;
return *this;
}
vec<T, Length> &operator=(vec<T, Length> &&other) {
this->value = std::move(other.value);
return *this;
}
template <typename O = T>
vec<T, Length> &operator=(std::array<O, Length> other) {
Data buffer = _priv_geom::cast_array(other);
this->value = buffer;
_priv_geom::cast_to_assignable(other, this->value);
return *this;
}
inline const ComponentRef &operator[](size_t index) {
assert_print(index < std::min(Length, static_cast<size_t>(4)),
"index out of bounds");
switch (index) {
case 0:
return this->x;
case 1:
return this->y;
case 2:
return this->z;
case 3:
return this->w;
default:
UNREACHABLE();
}
}
inline T operator[](size_t index) { return this->at(index); }
/// @brief Zero vector value.
static vec<T, Length> Zero() { return vec<T, Length>::uniform(0); }
@ -295,6 +212,9 @@ struct vec
return vec(buffer);
}
// NOTE: All of the following loops will get unrolled by the compiler because
// Length is a constant expression (unless Length is very large).
inline vec<T, Length> operator+(vec<T, Length> other) const {
Data result{this->value};
for (size_t i = 0; i < Length; i++) { result[i] += other.value[i]; }
@ -378,6 +298,28 @@ struct vec
}
}
/// @brief Computes component-wise vector minimum
/// @param other other vector
/// @returns new vector with min values
inline vec<T, Length> min(const vec<T, Length> &other) {
Data result{this->value};
for (size_t i = 0; i < Length; i++) {
result[i] = std::min(result[i], other.value[i]);
}
return vec<T, Length>(result);
}
/// @brief Computes component-wise vector maximum
/// @param other other vector
/// @returns new vector with max values
inline vec<T, Length> max(const vec<T, Length> &other) {
Data result{this->value};
for (size_t i = 0; i < Length; i++) {
result[i] = std::max(result[i], other.value[i]);
}
return vec<T, Length>(result);
}
inline T distance_squared(vec<T, Length> other) const {
vec<T, Length> buffer = other - *this;
buffer *= buffer;
@ -394,8 +336,28 @@ struct vec
T surface() const {
static_assert(Length == 2, "surface computable only for 2D vectors");
return this->get_x() * this->get_y();
return this->x() * this->y();
}
template <typename O>
vec<O, Length> cast() const {
Vc::array<O, Length> buffer;
_priv_geom::cast_to_assignable<Vc::array<T, Length>, O, Length,
Vc::array<O, Length>>(this->value, buffer);
return vec<O, Length>(buffer);
}
std::array<T, Length> to_array() const {
std::array<T, Length> result;
for (size_t i = 0; i < Length; ++i) { result[i] = this->value[i]; }
return result;
}
template <typename O>
operator vec<O, Length>() const {
return this->cast<O>();
}
operator std::array<T, Length>() const { return this->to_array(); }
};
template <typename T>
@ -414,33 +376,76 @@ using vec4f = vec4<float>;
using vec4d = vec4<double>;
using vec4i = vec4<std::int32_t>;
enum class rect_kind {
SIZED,
ABSOLUTE,
};
/// @brief 2D rectangle representation using position and size vectors.
/// @tparam T component number type.
template <typename T = std::int32_t>
template <typename T = std::int32_t, rect_kind Kind = rect_kind::SIZED>
struct rect {
static_assert(std::is_arithmetic_v<T>, "T must be a number");
using Component = T;
using ComponentRef = _priv_geom::_member_access<rect<T>, T>;
vec2<T> pos;
vec2<T> size;
private:
vec2<T> m_pos;
vec2<T> m_other;
rect() : pos(vec2<T>::Zero()), size(vec2<T>::Zero()) {}
rect(vec2<T> pos, vec2<T> size) : pos(pos), size(size) {}
public:
rect() : m_pos(vec2<T>::Zero()), m_other(vec2<T>::Zero()) {}
rect(vec2<T> pos, vec2<T> other) : m_pos(pos), m_other(other) {}
/// @brief Rectangle x position.
/// @return x position of this rectangle.
T get_x() const { return this->pos.get_x(); }
inline T x() const { return this->m_pos.x(); }
/// @brief Rectangle y position.
/// @return y position of this rectangle.
T get_y() const { return this->pos.get_y(); }
inline T y() const { return this->m_pos.y(); }
inline vec2<T> pos() const { return this->m_pos; }
inline vec2<T> size() const {
if constexpr (Kind == rect_kind::SIZED) {
return this->m_other;
} else {
return this->m_other - this->m_pos;
}
}
inline vec2<T> end_pos() const {
if constexpr (Kind == rect_kind::SIZED) {
return this->m_pos + this->m_other;
} else {
return this->m_other;
}
}
/// @brief Rectangle end x position.
/// @return ending x position of this rectangle.
inline T end_x() const { return this->end_pos().x(); }
/// @brief Rectangle end y position.
/// @return ending y position of this rectangle.
inline T end_y() const { return this->end_pos().y(); }
/// @brief Rectangle width.
/// @return width of this rectangle.
T get_width() const { return this->size.get_x(); }
inline T width() const {
if constexpr (Kind == rect_kind::SIZED) {
return this->m_other.x();
} else {
return this->m_other.x() + this->m_pos.x();
}
}
/// @brief Rectangle height.
/// @return height of this rectangle.
T get_height() const { return this->size.get_y(); }
inline T height() const {
if constexpr (Kind == rect_kind::SIZED) {
return this->m_other.y();
} else {
return this->m_other.y() + this->m_pos.y();
}
}
/// @brief Returns rectangle component at `index`.
/// @param index component index.
@ -449,123 +454,200 @@ struct rect {
assert_print(index < static_cast<size_t>(4), "index out of bounds");
switch (index) {
case 0:
return this->get_x();
return this->m_pos.x();
case 1:
return this->get_y();
return this->m_pos.y();
case 2:
return this->get_width();
return this->m_other.x();
case 3:
return this->get_height();
return this->m_other.y();
default:
UNREACHABLE();
}
}
void set_x(T value) { this->pos.set_x(value); }
void set_y(T value) { this->pos.set_y(value); }
void set_width(T value) { this->size.set_x(value); }
void set_height(T value) { this->size.set_y(value); }
inline void set_pos(vec2<T> value) { this->m_pos = value; }
inline void set_pos(T x, T y) { this->set_pos(vec2<T>(x, y)); }
inline void set_size(vec2<T> value) {
if constexpr (Kind == rect_kind::SIZED) {
this->m_other = value;
} else {
this->m_other = this->m_pos + value;
}
}
inline void set_size(T width, T height) {
this->set_size(vec2<T>(width, height));
}
inline void set_end_pos(vec2<T> value) {
if constexpr (Kind == rect_kind::SIZED) {
this->m_other = value - this->m_pos;
} else {
this->m_other = value;
}
}
inline void set_end_pos(T x, T y) { this->set_end_pos(vec2<T>(x, y)); }
inline void set_x(T value) { this->m_pos.set_x(value); }
inline void set_y(T value) { this->m_pos.set_y(value); }
inline void set_width(T value) {
if constexpr (Kind == rect_kind::SIZED) {
this->other.set_x(value);
} else {
this->other.set_x(this->m_pos.get_x() + value);
}
}
inline void set_height(T value) {
if constexpr (Kind == rect_kind::SIZED) {
this->m_other.set_y(value);
} else {
this->m_other.set_y(this->m_pos.get_y() + value);
}
}
inline void set_end_x(T value) {
if constexpr (Kind == rect_kind::SIZED) {
this->m_other.set_x(value - this->m_pos.get_x());
} else {
this->m_other.set_x(value);
}
}
inline void set_end_y(T value) {
if constexpr (Kind == rect_kind::SIZED) {
this->m_other.set_y(value - this->m_pos.get_y());
} else {
this->m_other.set_y(value);
}
}
void set(size_t index, T value) {
assert_print(index < static_cast<size_t>(4), "index out of bounds");
switch (index) {
case 0:
return this->set_x(value);
return this->m_pos.set_x(value);
case 1:
return this->set_y(value);
return this->m_pos.set_y(value);
case 2:
return this->set_width(value);
return this->m_other.set_x(value);
case 3:
return this->set_height(value);
return this->m_other.set_y(value);
default:
UNREACHABLE();
}
}
/// @brief rectangle position x value.
///
/// Treat it as `T`. Use `*x` in case type coertion is needed.
const ComponentRef x = ComponentRef(this, 0);
/// @brief rectangle position y value.
///
/// Treat it as `T`. Use `*y` in case type coertion is needed.
const ComponentRef y = ComponentRef(this, 1);
/// @brief rectangle width value.
///
/// Treat it as `T`. Use `*width` in case type coertion is needed.
const ComponentRef width = ComponentRef(this, 2);
/// @brief rectangle height value.
///
/// Treat it as `T`. Use `*height` in case type coertion is needed.
const ComponentRef height = ComponentRef(this, 3);
std::array<vec2<T>, 4> corners() const {
return std::array<vec2<T>, 4>{
this->pos,
this->pos + vec2<T>(this->get_width(), 0),
this->pos + this->size,
this->pos + vec2<T>(0, this->get_height()),
this->m_pos,
this->m_pos + vec2<T>(this->get_width(), 0),
this->get_end_pos(),
this->m_pos + vec2<T>(0, this->get_height()),
};
}
template <typename O = T>
bool contains(vec2<O> p) const {
return p.get_x() >= this->get_x() &&
p.get_x() < this->get_x() + this->get_width() &&
p.get_y() >= this->get_y() &&
p.get_y() < this->get_y() + this->get_height();
return p.x() >= this->x() && p.x() < this->x() + this->width() &&
p.y() >= this->y() && p.y() < this->y() + this->height();
}
template <typename O = T>
bool contains(rect<O> other) const {
return contains(other.pos) &&
contains(other.pos + vec2<O>(other.get_width(), 0)) &&
contains(other.pos + other.size) &&
contains(other.pos + vec2<O>(0, other.get_height()));
return contains(other.m_pos) &&
contains(other.m_pos + vec2<O>(other.width(), 0)) &&
contains(other.m_pos + other.m_other) &&
contains(other.m_pos + vec2<O>(0, other.height()));
}
private:
template <typename O = T>
bool _intersects_partial(rect<O> other) const {
return contains(other.pos) ||
contains(other.pos + vec2<O>(other.get_width(), 0)) ||
contains(other.pos + other.size) ||
contains(other.pos + vec2<O>(0, other.get_height()));
return contains(other.m_pos) ||
contains(other.m_pos + vec2<O>(other.width(), 0)) ||
contains(other.m_pos + other.m_other) ||
contains(other.m_pos + vec2<O>(0, other.height()));
}
public:
template <typename O = T>
bool intersects(rect<O> other) const {
return this->_intersects_partial(other) || other._intersects_partial(*this);
return this->_intersects_partial(m_other) ||
other._intersects_partial(*this);
}
constexpr const ComponentRef &operator[](size_t index) {
assert_print(index < static_cast<size_t>(4), "index out of bounds");
switch (index) {
case 0:
return this->x;
case 1:
return this->y;
case 2:
return this->width;
case 3:
return this->height;
default:
UNREACHABLE();
rect<T, Kind> &operator=(const rect<T, Kind> &other) {
this->m_pos = other.m_pos;
this->m_other = other.m_other;
return *this;
}
rect<T, Kind> &operator=(rect<T, Kind> &&other) {
this->m_pos = other.m_pos;
this->m_other = other.m_other;
return *this;
}
template <typename O = T>
rect<T, Kind> &operator=(std::array<O, 4> other) {
_priv_geom::cast_to_assignable(other.m_pos, this->m_pos);
_priv_geom::cast_to_assignable(other.m_other, this->m_other);
return *this;
}
inline T operator[](size_t index) {
if (index < 2) {
return this->m_pos[index];
} else if (index < 4) {
return this->m_other[index - 2];
} else {
CRIT_ERR("index out of bounds");
}
}
#ifdef BUILD_X11
XRectangle to_xrectangle() const {
return XRectangle{
.x = static_cast<short>(this->get_x()),
.y = static_cast<short>(this->get_y()),
.width = static_cast<unsigned short>(this->get_width()),
.height = static_cast<unsigned short>(this->get_height())};
return XRectangle{.x = static_cast<short>(this->x()),
.y = static_cast<short>(this->y()),
.width = static_cast<unsigned short>(this->width()),
.height = static_cast<unsigned short>(this->height())};
}
#endif /* BUILD_X11 */
rect<T, rect_kind::SIZED> to_sized() const {
if constexpr (Kind == rect_kind::SIZED) {
return *this;
} else {
return rect<T, rect_kind::SIZED>{this->m_pos,
this->m_other - this->m_pos};
}
}
rect<T, rect_kind::ABSOLUTE> to_absolute() const {
if constexpr (Kind == rect_kind::ABSOLUTE) {
return *this;
} else {
return rect<T, rect_kind::ABSOLUTE>{this->m_pos,
this->m_pos + this->m_other};
}
}
std::array<T, 4> to_array() const {
return std::array<T, 4>{this->m_pos.x(), this->m_pos.y(), this->m_other.x(),
this->m_other.y()};
}
inline operator std::array<T, 4>() const { return this->to_array(); }
inline explicit operator rect<T, rect_kind::SIZED>() const {
return this->to_sized();
}
inline explicit operator rect<T, rect_kind::ABSOLUTE>() const {
return this->to_absolute();
}
};
template <typename T>
using sized_rect = rect<T>;
template <typename T>
using absolute_rect = rect<T, rect_kind::ABSOLUTE>;
} // namespace conky
#endif /* _CONKY_GEOMETRY_H_ */

View File

@ -49,7 +49,7 @@
#endif
/* workarea where window / text is aligned (from _NET_WORKAREA on X11) */
conky::rect<int> workarea;
conky::absolute_rect<int> workarea;
/* Window stuff */
char window_created = 0;

View File

@ -161,7 +161,7 @@ inline bool TEST_HINT(uint16_t mask, window_hints hint) {
}
#endif
extern conky::rect<int> workarea;
extern conky::absolute_rect<int> workarea;
extern char window_created;

View File

@ -593,17 +593,17 @@ void llua_setup_window_table(conky::rect<int> text_rect) {
#ifdef BUILD_GUI
if (out_to_gui(*state)) {
#ifdef BUILD_X11
llua_set_number("width", window.geometry.width);
llua_set_number("height", window.geometry.height);
llua_set_number("width", window.geometry.width());
llua_set_number("height", window.geometry.height());
#endif /*BUILD_X11*/
llua_set_number("border_inner_margin", border_inner_margin.get(*state));
llua_set_number("border_outer_margin", border_outer_margin.get(*state));
llua_set_number("border_width", border_width.get(*state));
llua_set_number("text_start_x", text_rect.x);
llua_set_number("text_start_y", text_rect.y);
llua_set_number("text_width", text_rect.width);
llua_set_number("text_height", text_rect.height);
llua_set_number("text_start_x", text_rect.x());
llua_set_number("text_start_y", text_rect.y());
llua_set_number("text_width", text_rect.width());
llua_set_number("text_height", text_rect.height());
lua_setglobal(lua_L, "conky_window");
}
@ -621,14 +621,14 @@ void llua_update_window_table(conky::rect<int> text_rect) {
}
#ifdef BUILD_X11
llua_set_number("width", window.geometry.width);
llua_set_number("height", window.geometry.height);
llua_set_number("width", window.geometry.width());
llua_set_number("height", window.geometry.height());
#endif /*BUILD_X11*/
llua_set_number("text_start_x", text_rect.x);
llua_set_number("text_start_y", text_rect.y);
llua_set_number("text_width", text_rect.width);
llua_set_number("text_height", text_rect.height);
llua_set_number("text_start_x", text_rect.x());
llua_set_number("text_start_y", text_rect.y());
llua_set_number("text_width", text_rect.width());
llua_set_number("text_height", text_rect.height());
lua_setglobal(lua_L, "conky_window");
}

View File

@ -191,10 +191,10 @@ void mouse_event::push_lua_table(lua_State *L) const {
}
void mouse_positioned_event::push_lua_data(lua_State *L) const {
push_table_value(L, "x", this->pos.x);
push_table_value(L, "y", this->pos.y);
push_table_value(L, "x_abs", this->pos_absolute.x);
push_table_value(L, "y_abs", this->pos_absolute.y);
push_table_value(L, "x", this->pos.x());
push_table_value(L, "y", this->pos.y());
push_table_value(L, "x_abs", this->pos_absolute.x());
push_table_value(L, "y_abs", this->pos_absolute.y());
}
void mouse_move_event::push_lua_data(lua_State *L) const {
@ -523,10 +523,10 @@ std::vector<std::tuple<int, XEvent *>> xi_event_data::generate_events(
e->window = target;
e->subwindow = child;
e->time = CurrentTime;
e->x = static_cast<int>(target_pos.x);
e->y = static_cast<int>(target_pos.y);
e->x_root = static_cast<int>(this->pos_absolute.x);
e->y_root = static_cast<int>(this->pos_absolute.y);
e->x = static_cast<int>(target_pos.x());
e->y = static_cast<int>(target_pos.y());
e->x_root = static_cast<int>(this->pos_absolute.x());
e->y_root = static_cast<int>(this->pos_absolute.y());
e->state = this->mods.effective;
e->is_hint = NotifyNormal;
e->same_screen = True;
@ -556,10 +556,10 @@ std::vector<std::tuple<int, XEvent *>> xi_event_data::generate_events(
e->window = target;
e->subwindow = child;
e->time = CurrentTime;
e->x = static_cast<int>(target_pos.x);
e->y = static_cast<int>(target_pos.y);
e->x_root = static_cast<int>(this->pos_absolute.x);
e->y_root = static_cast<int>(this->pos_absolute.y);
e->x = static_cast<int>(target_pos.x());
e->y = static_cast<int>(target_pos.y());
e->x_root = static_cast<int>(this->pos_absolute.x());
e->y_root = static_cast<int>(this->pos_absolute.y());
e->state = this->mods.effective;
e->button = scroll_direction;
e->same_screen = True;
@ -582,10 +582,10 @@ std::vector<std::tuple<int, XEvent *>> xi_event_data::generate_events(
e->window = target;
e->subwindow = child;
e->time = CurrentTime;
e->x = static_cast<int>(target_pos.x);
e->y = static_cast<int>(target_pos.y);
e->x_root = static_cast<int>(this->pos_absolute.x);
e->y_root = static_cast<int>(this->pos_absolute.y);
e->x = static_cast<int>(target_pos.x());
e->y = static_cast<int>(target_pos.y());
e->x_root = static_cast<int>(this->pos_absolute.x());
e->y_root = static_cast<int>(this->pos_absolute.y());
e->state = this->mods.effective;
e->button = this->detail;
e->same_screen = True;

View File

@ -226,7 +226,7 @@ char *find_and_replace_templates(const char *inbuf) {
outlen += len;
*o = '\0';
outbuf = static_cast<char *>(realloc(outbuf, outlen * sizeof(char)));
strncat(outbuf, tmpl_out, len);
strcat(outbuf, tmpl_out);
free(tmpl_out);
o = outbuf + strlen(outbuf);
} else {

View File

@ -180,8 +180,12 @@ static int x11_error_handler(Display *d, XErrorEvent *err) {
error_name, reinterpret_cast<uint64_t>(err->display),
static_cast<int64_t>(err->resourceid), err->serial, code_description);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfree-nonheap-object"
// *_allocated takes care of avoiding freeing unallocated objects
if (name_allocated) delete[] error_name;
if (code_allocated) delete[] code_description;
#pragma GCC diagnostic pop
return 0;
}
@ -321,9 +325,9 @@ void update_x11_resource_db(bool first_run) {
void update_x11_workarea() {
/* default work area is display */
workarea.pos = conky::vec2i();
workarea.width = DisplayWidth(display, screen);
workarea.height = DisplayHeight(display, screen);
workarea = conky::absolute_rect<int>(
conky::vec2i::Zero(), conky::vec2i(DisplayWidth(display, screen),
DisplayHeight(display, screen)));
#ifdef BUILD_XINERAMA
/* if xinerama is being used, adjust workarea to the head's area */
@ -352,10 +356,8 @@ void update_x11_workarea() {
}
XineramaScreenInfo *ps = &si[i];
workarea[0] = ps->x_org;
workarea[1] = ps->y_org;
workarea[2] = workarea[0] + ps->width;
workarea[3] = workarea[1] + ps->height;
workarea.set_pos(ps->x_org, ps->y_org);
workarea.set_size(ps->width, ps->height);
XFree(si);
DBGP("Fixed xinerama area to: %d %d %d %d", workarea[0], workarea[1],
@ -375,8 +377,8 @@ static Window find_desktop_window(Window root) {
int display_height = DisplayHeight(display, screen);
desktop = find_desktop_window_impl(root, display_width, display_height);
update_x11_workarea();
desktop = find_desktop_window_impl(desktop, workarea[2] - workarea[0],
workarea[3] - workarea[1]);
desktop =
find_desktop_window_impl(desktop, workarea.width(), workarea.height());
if (desktop != root) {
NORM_ERR("desktop window (0x%lx) is subwindow of root window (0x%lx)",
@ -551,9 +553,9 @@ void x11_init_window(lua::state &l, bool own) {
}
/* Parent is desktop window (which might be a child of root) */
window.window = XCreateWindow(display, window.desktop, window.geometry.x,
window.geometry.y, b, b, 0, depth,
InputOutput, visual, flags, &attrs);
window.window = XCreateWindow(
display, window.desktop, window.geometry.x(), window.geometry.y(), b,
b, 0, depth, InputOutput, visual, flags, &attrs);
XLowerWindow(display, window.window);
XSetClassHint(display, window.window, &classHint);
@ -592,11 +594,11 @@ void x11_init_window(lua::state &l, bool own) {
}
if (own_window_type.get(l) == window_type::DOCK) {
window.geometry.pos = conky::vec2i::Zero();
window.geometry.set_pos(conky::vec2i::Zero());
}
/* Parent is root window so WM can take control */
window.window = XCreateWindow(display, window.root, window.geometry.x,
window.geometry.y, b, b, 0, depth,
window.window = XCreateWindow(display, window.root, window.geometry.x(),
window.geometry.y(), b, b, 0, depth,
InputOutput, visual, flags, &attrs);
uint16_t hints = own_window_hints.get(l);
@ -793,7 +795,7 @@ void x11_init_window(lua::state &l, bool own) {
if (window.window == None) { window.window = window.desktop; }
if (XGetWindowAttributes(display, window.window, &attrs) != 0) {
window.geometry.size = conky::vec2i(attrs.width, attrs.height);
window.geometry.set_size(attrs.width, attrs.height);
}
NORM_ERR("drawing to desktop window");
@ -1139,44 +1141,46 @@ void set_struts(alignment align) {
if (strut != None) {
long sizes[STRUT_COUNT] = {0};
int display_width = workarea[2] - workarea[0];
int display_height = workarea[3] - workarea[1];
int display_width = workarea.width();
int display_height = workarea.height();
switch (horizontal_alignment(align)) {
case axis_align::START:
sizes[*x11_strut::LEFT] = std::clamp(
window.geometry.x + window.geometry.width, 0, *workarea.width);
window.geometry.x() + window.geometry.end_x(), 0, display_width);
sizes[*x11_strut::LEFT_START_Y] =
std::clamp(*window.geometry.y, 0, *workarea.height);
std::clamp(window.geometry.y(), 0, display_height);
sizes[*x11_strut::LEFT_END_Y] = std::clamp(
window.geometry.y + window.geometry.height, 0, *workarea.height);
window.geometry.y() + window.geometry.height(), 0, display_height);
break;
case axis_align::END:
sizes[*x11_strut::RIGHT] =
std::clamp(workarea.width - window.geometry.x, 0, *workarea.width);
std::clamp(display_width - window.geometry.x(), 0, display_width);
sizes[*x11_strut::RIGHT_START_Y] =
std::clamp(*window.geometry.y, 0, *workarea.height);
std::clamp(window.geometry.y(), 0, display_height);
sizes[*x11_strut::RIGHT_END_Y] = std::clamp(
window.geometry.y + window.geometry.height, 0, *workarea.height);
window.geometry.y() + window.geometry.height(), 0, display_height);
break;
case axis_align::MIDDLE:
switch (vertical_alignment(align)) {
case axis_align::START:
sizes[*x11_strut::TOP] =
std::clamp(window.geometry.y + window.geometry.height, 0,
*workarea.height);
std::clamp(window.geometry.y() + window.geometry.height(), 0,
display_height);
sizes[*x11_strut::TOP_START_X] =
std::clamp(*window.geometry.x, 0, *workarea.width);
sizes[*x11_strut::TOP_END_X] = std::clamp(
window.geometry.x + window.geometry.width, 0, *workarea.width);
std::clamp(window.geometry.x(), 0, display_width);
sizes[*x11_strut::TOP_END_X] =
std::clamp(window.geometry.x() + window.geometry.width(), 0,
display_width);
break;
case axis_align::END:
sizes[*x11_strut::BOTTOM] = std::clamp(
workarea.height - window.geometry.y, 0, *workarea.height);
display_height - window.geometry.y(), 0, display_height);
sizes[*x11_strut::BOTTOM_START_X] =
std::clamp(*window.geometry.x, 0, *workarea.width);
sizes[*x11_strut::BOTTOM_END_X] = std::clamp(
window.geometry.x + window.geometry.width, 0, *workarea.width);
std::clamp(window.geometry.x(), 0, display_width);
sizes[*x11_strut::BOTTOM_END_X] =
std::clamp(window.geometry.x() + window.geometry.width(), 0,
display_width);
break;
case axis_align::MIDDLE:
// can't reserve space in middle of the screen
@ -1335,7 +1339,7 @@ void propagate_xinput_event(const conky::xi_event_data *ev) {
int read_x, read_y;
// Update event x and y coordinates to be target window relative
XTranslateCoordinates(display, window.desktop, ev->event,
ev->pos_absolute.x, ev->pos_absolute.y, &read_x,
ev->pos_absolute.x(), ev->pos_absolute.y(), &read_x,
&read_y, &child);
target_pos = conky::vec2i(read_x, read_y);
}
@ -1536,8 +1540,8 @@ std::vector<Window> query_x11_windows_at_pos(
&_ignore);
XGetWindowAttributes(display, current, &attr);
if (pos_x <= pos.x && pos_y <= pos.y && pos_x + attr.width >= pos.x &&
pos_y + attr.height >= pos.y && predicate(attr)) {
if (pos_x <= pos.x() && pos_y <= pos.y() && pos_x + attr.width >= pos.x() &&
pos_y + attr.height >= pos.y() && predicate(attr)) {
result.push_back(current);
}
}