wip(refactor): Cairo drawing
This commit is contained in:
parent
452afcdc68
commit
a59e115622
@ -11,6 +11,7 @@
|
||||
#include "cairo/utils.hpp"
|
||||
#include "common.hpp"
|
||||
#include "components/logger.hpp"
|
||||
#include "components/types.hpp"
|
||||
#include "errors.hpp"
|
||||
#include "utils/color.hpp"
|
||||
#include "utils/string.hpp"
|
||||
@ -63,6 +64,9 @@ namespace cairo {
|
||||
}
|
||||
|
||||
context& operator<<(const abspos& p) {
|
||||
if (p.clear) {
|
||||
cairo_new_path(m_c);
|
||||
}
|
||||
cairo_move_to(m_c, p.x, p.y);
|
||||
return *this;
|
||||
}
|
||||
@ -117,8 +121,24 @@ namespace cairo {
|
||||
return *this;
|
||||
}
|
||||
|
||||
context& operator<<(const rounded_corners& c) {
|
||||
double radius = c.radius / 1.0;
|
||||
double d = M_PI / 180.0;
|
||||
cairo_new_sub_path(m_c);
|
||||
cairo_arc(m_c, c.x + c.w - radius, c.y + radius, radius, -90 * d, 0 * d);
|
||||
cairo_arc(m_c, c.x + c.w - radius, c.y + c.h - radius, radius, 0 * d, 90 * d);
|
||||
cairo_arc(m_c, c.x + radius, c.y + c.h - radius, radius, 90 * d, 180 * d);
|
||||
cairo_arc(m_c, c.x + radius, c.y + radius, radius, 180 * d, 270 * d);
|
||||
cairo_close_path(m_c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
context& operator<<(const textblock& t) {
|
||||
// Sort the fontlist so that the preferred font is tested first
|
||||
double x, y;
|
||||
position(&x, &y);
|
||||
|
||||
// Sort the fontlist so that the
|
||||
// preferred font gets prioritized
|
||||
auto& fns = m_fonts;
|
||||
std::sort(fns.begin(), fns.end(), [&](const unique_ptr<font>& a, const unique_ptr<font>&) {
|
||||
if (t.fontindex > 0 && std::distance(fns.begin(), std::find(fns.begin(), fns.end(), a)) == t.fontindex - 1) {
|
||||
@ -147,18 +167,56 @@ namespace cairo {
|
||||
end++;
|
||||
}
|
||||
|
||||
f->use(m_c);
|
||||
// encapsulate the vert. centering
|
||||
save();
|
||||
{
|
||||
*this << abspos{x, y};
|
||||
|
||||
cairo_text_extents_t extents;
|
||||
f->textwidth(utf8, &extents);
|
||||
f->use();
|
||||
|
||||
save(); // encapsulate the y pos update
|
||||
*this << relpos{0.0, extents.height / 2.0 - f->extents().descent + f->offset()};
|
||||
f->render(subset);
|
||||
cairo_text_extents_t extents;
|
||||
f->textwidth(utf8, &extents);
|
||||
double dx{0.0}, dy{0.0};
|
||||
|
||||
if (t.align == alignment::CENTER) {
|
||||
dx -= extents.x_advance / 2.0;
|
||||
|
||||
save();
|
||||
{
|
||||
cairo_rectangle(m_c, x, y, extents.x_advance / 2.0, extents.height);
|
||||
auto pattern = cairo_pattern_create_rgba(1.0, 0.0, 0.0, 0.0);
|
||||
cairo_set_source(m_c, pattern);
|
||||
cairo_translate(m_c, dx, 0.0);
|
||||
cairo_set_operator(m_c, CAIRO_OPERATOR_DEST);
|
||||
cairo_fill(m_c);
|
||||
cairo_pattern_destroy(pattern);
|
||||
}
|
||||
restore();
|
||||
} else if (t.align == alignment::RIGHT) {
|
||||
dx -= extents.x_advance;
|
||||
|
||||
save();
|
||||
{
|
||||
cairo_rectangle(m_c, x, y, extents.x_advance, extents.height);
|
||||
auto pattern = cairo_pattern_create_rgba(0.0, 0.0, 0.0, 0.0);
|
||||
cairo_set_source(m_c, pattern);
|
||||
cairo_set_operator(m_c, CAIRO_OPERATOR_DEST);
|
||||
cairo_translate(m_c, dx, 0.0);
|
||||
cairo_fill(m_c);
|
||||
cairo_pattern_destroy(pattern);
|
||||
}
|
||||
restore();
|
||||
}
|
||||
|
||||
auto fontextents = f->extents();
|
||||
f->render(subset, x + dx,
|
||||
y + dy - (extents.height / 2.0 + extents.y_bearing + fontextents.descent) + f->offset());
|
||||
position(&x, nullptr);
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
restore();
|
||||
|
||||
*this << relpos{extents.width, 0.0};
|
||||
|
||||
chars.erase(chars.begin(), end);
|
||||
break;
|
||||
}
|
||||
@ -179,6 +237,8 @@ namespace cairo {
|
||||
chars.erase(chars.begin(), ++chars.begin());
|
||||
}
|
||||
|
||||
*this << abspos{x, y};
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -197,11 +257,11 @@ namespace cairo {
|
||||
}
|
||||
|
||||
context& restore(bool restore_point = true) {
|
||||
cairo_restore(m_c);
|
||||
if (restore_point) {
|
||||
*this << abspos{m_points.front().first, m_points.front().first};
|
||||
m_points.pop_front();
|
||||
}
|
||||
cairo_restore(m_c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -215,8 +275,12 @@ namespace cairo {
|
||||
return *this;
|
||||
}
|
||||
|
||||
context& fill() {
|
||||
cairo_fill(m_c);
|
||||
context& fill(bool preserve = false) {
|
||||
if (preserve) {
|
||||
cairo_fill_preserve(m_c);
|
||||
} else {
|
||||
cairo_fill(m_c);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -231,10 +295,11 @@ namespace cairo {
|
||||
return *this;
|
||||
}
|
||||
|
||||
context& position(double* x, double* y) {
|
||||
*x = 0.0;
|
||||
*y = 0.0;
|
||||
context& position(double* x, double* y = nullptr) {
|
||||
if (cairo_has_current_point(m_c)) {
|
||||
double x_, y_;
|
||||
x = x != nullptr ? x : &x_;
|
||||
y = y != nullptr ? y : &y_;
|
||||
cairo_get_current_point(m_c, x, y);
|
||||
}
|
||||
return *this;
|
||||
|
@ -63,25 +63,23 @@ namespace cairo {
|
||||
class font {
|
||||
public:
|
||||
explicit font(cairo_t* cairo, double offset) : m_cairo(cairo), m_offset(offset) {}
|
||||
virtual ~font() {};
|
||||
virtual ~font(){};
|
||||
|
||||
virtual string name() const = 0;
|
||||
virtual string file() const = 0;
|
||||
virtual double offset() const = 0;
|
||||
virtual double size() const = 0;
|
||||
|
||||
virtual void use(cairo_t* c) {
|
||||
cairo_set_font_face(c, cairo_font_face_reference(m_font_face));
|
||||
virtual cairo_font_extents_t extents() = 0;
|
||||
|
||||
virtual void use() {
|
||||
cairo_set_font_face(m_cairo, cairo_font_face_reference(m_font_face));
|
||||
}
|
||||
|
||||
virtual size_t match(unicode_charlist& charlist) = 0;
|
||||
virtual size_t render(const string& text) = 0;
|
||||
virtual size_t render(const string& text, double x = 0.0, double y = 0.0, bool reverse = false) = 0;
|
||||
virtual void textwidth(const string& text, cairo_text_extents_t* extents) = 0;
|
||||
|
||||
cairo_font_extents_t extents() const {
|
||||
return m_extents;
|
||||
}
|
||||
|
||||
protected:
|
||||
cairo_t* m_cairo;
|
||||
cairo_font_face_t* m_font_face{nullptr};
|
||||
@ -111,7 +109,7 @@ namespace cairo {
|
||||
throw application_error(sstream() << "cairo_scaled_font_create(): " << cairo_status_to_string(status));
|
||||
}
|
||||
|
||||
auto lock = make_unique<details::ft_face_lock>(cairo_scaled_font_reference(m_scaled));
|
||||
auto lock = make_unique<details::ft_face_lock>(m_scaled);
|
||||
auto face = static_cast<FT_Face>(*lock);
|
||||
|
||||
if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) == FT_Err_Ok) {
|
||||
@ -121,6 +119,8 @@ namespace cairo {
|
||||
} else if (FT_Select_Charmap(face, FT_ENCODING_SJIS) == FT_Err_Ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
lock.reset();
|
||||
}
|
||||
|
||||
~font_fc() override {
|
||||
@ -132,6 +132,11 @@ namespace cairo {
|
||||
}
|
||||
}
|
||||
|
||||
cairo_font_extents_t extents() override {
|
||||
cairo_scaled_font_extents(m_scaled, &m_extents);
|
||||
return m_extents;
|
||||
}
|
||||
|
||||
string name() const override {
|
||||
return property("family");
|
||||
}
|
||||
@ -157,12 +162,12 @@ namespace cairo {
|
||||
return px;
|
||||
}
|
||||
|
||||
void use(cairo_t* c) override {
|
||||
cairo_set_scaled_font(c, cairo_scaled_font_reference(m_scaled));
|
||||
void use() override {
|
||||
cairo_set_scaled_font(m_cairo, m_scaled);
|
||||
}
|
||||
|
||||
size_t match(unicode_charlist& charlist) override {
|
||||
auto lock = make_unique<details::ft_face_lock>(cairo_scaled_font_reference(m_scaled));
|
||||
auto lock = make_unique<details::ft_face_lock>(m_scaled);
|
||||
auto face = static_cast<FT_Face>(*lock);
|
||||
size_t available_chars = 0;
|
||||
for (auto&& c : charlist) {
|
||||
@ -176,20 +181,22 @@ namespace cairo {
|
||||
return available_chars;
|
||||
}
|
||||
|
||||
size_t render(const string& text) override {
|
||||
double x, y;
|
||||
cairo_get_current_point(m_cairo, &x, &y);
|
||||
|
||||
size_t render(const string& text, double x = 0.0, double y = 0.0, bool reverse = false) override {
|
||||
cairo_glyph_t* glyphs{nullptr};
|
||||
cairo_text_cluster_t* clusters{nullptr};
|
||||
cairo_text_cluster_flags_t cf{};
|
||||
int nglyphs = 0, nclusters = 0;
|
||||
|
||||
if (reverse) {
|
||||
cf = CAIRO_TEXT_CLUSTER_FLAG_BACKWARD;
|
||||
}
|
||||
|
||||
string utf8 = string(text);
|
||||
auto status = cairo_scaled_font_text_to_glyphs(cairo_scaled_font_reference(m_scaled), x, y, utf8.c_str(),
|
||||
utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf);
|
||||
auto status = cairo_scaled_font_text_to_glyphs(
|
||||
m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf);
|
||||
|
||||
if (status != CAIRO_STATUS_SUCCESS) {
|
||||
throw application_error(sstream() << "cairo_scaled_font_status()" << cairo_status_to_string(status));
|
||||
throw application_error(sstream() << "cairo_scaled_font_text_to_glyphs()" << cairo_status_to_string(status));
|
||||
}
|
||||
|
||||
size_t bytes = 0;
|
||||
@ -201,18 +208,36 @@ namespace cairo {
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes) {
|
||||
if (bytes && bytes < text.size()) {
|
||||
cairo_glyph_free(glyphs);
|
||||
cairo_text_cluster_free(clusters);
|
||||
|
||||
utf8 = text.substr(0, bytes);
|
||||
cairo_scaled_font_text_to_glyphs(
|
||||
auto status = cairo_scaled_font_text_to_glyphs(
|
||||
m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf);
|
||||
cairo_show_text_glyphs(m_cairo, utf8.c_str(), utf8.size(), glyphs, nglyphs, clusters, nclusters, cf);
|
||||
|
||||
if (status != CAIRO_STATUS_SUCCESS) {
|
||||
throw application_error(sstream() << "cairo_scaled_font_text_to_glyphs()" << cairo_status_to_string(status));
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes) {
|
||||
cairo_text_extents_t extents{};
|
||||
cairo_scaled_font_glyph_extents(m_scaled, glyphs, nglyphs, &extents);
|
||||
cairo_show_text_glyphs(m_cairo, utf8.c_str(), utf8.size(), glyphs, nglyphs, clusters, nclusters, cf);
|
||||
cairo_rel_move_to(m_cairo, extents.x_advance, 0.0);
|
||||
// cairo_glyph_path(m_cairo, glyphs, nglyphs);
|
||||
cairo_fill_preserve(m_cairo);
|
||||
}
|
||||
|
||||
cairo_glyph_free(glyphs);
|
||||
cairo_text_cluster_free(clusters);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void textwidth(const string& text, cairo_text_extents_t* extents) override {
|
||||
cairo_scaled_font_text_extents(cairo_scaled_font_reference(m_scaled), text.c_str(), extents);
|
||||
cairo_scaled_font_text_extents(m_scaled, text.c_str(), extents);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -4,10 +4,13 @@
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
enum class alignment;
|
||||
|
||||
namespace cairo {
|
||||
struct abspos {
|
||||
double x;
|
||||
double y;
|
||||
bool clear{true};
|
||||
};
|
||||
struct relpos {
|
||||
double x;
|
||||
@ -37,9 +40,18 @@ namespace cairo {
|
||||
vector<unsigned int> steps;
|
||||
};
|
||||
|
||||
struct rounded_corners {
|
||||
double x;
|
||||
double y;
|
||||
double w;
|
||||
double h;
|
||||
double radius;
|
||||
};
|
||||
|
||||
struct textblock {
|
||||
alignment align;
|
||||
string contents;
|
||||
unsigned char fontindex;
|
||||
int fontindex;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -145,6 +145,7 @@ struct bar_settings {
|
||||
|
||||
std::unordered_map<edge, border_settings, enum_hash> borders{};
|
||||
|
||||
double radius{0.0};
|
||||
int spacing{0};
|
||||
string separator{};
|
||||
|
||||
|
@ -136,6 +136,7 @@ bar::bar(connection& conn, signal_emitter& emitter, const config& config, const
|
||||
m_opts.spacing = m_conf.get(bs, "spacing", m_opts.spacing);
|
||||
m_opts.separator = m_conf.get(bs, "separator", ""s);
|
||||
m_opts.locale = m_conf.get(bs, "locale", ""s);
|
||||
m_opts.radius = m_conf.get(bs, "radius", m_opts.radius);
|
||||
|
||||
try {
|
||||
auto padding = m_conf.get<decltype(m_opts.padding.left)>(bs, "module-padding");
|
||||
|
@ -256,8 +256,8 @@ void renderer::flush() {
|
||||
/**
|
||||
* Reserve space at given edge
|
||||
*/
|
||||
void renderer::reserve_space(edge side, unsigned short int w) {
|
||||
m_log.trace_x("renderer: reserve_space(%i, %i)", static_cast<unsigned char>(side), w);
|
||||
void renderer::reserve_space(edge side, unsigned int w) {
|
||||
m_log.trace_x("renderer: reserve_space(%i, %i)", static_cast<int>(side), w);
|
||||
|
||||
m_cleararea.side = side;
|
||||
m_cleararea.size = w;
|
||||
@ -295,6 +295,16 @@ void renderer::fill_background() {
|
||||
m_context->save();
|
||||
*m_context << m_compositing_background;
|
||||
|
||||
if (m_bar.radius != 0.0) {
|
||||
// clang-format off
|
||||
*m_context << cairo::rounded_corners{
|
||||
static_cast<double>(m_rect.x),
|
||||
static_cast<double>(m_rect.y),
|
||||
static_cast<double>(m_rect.width),
|
||||
static_cast<double>(m_rect.height), m_bar.radius};
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
if (!m_bar.background_steps.empty()) {
|
||||
m_log.trace_x("renderer: gradient background (steps=%lu)", m_bar.background_steps.size());
|
||||
*m_context << cairo::linear_gradient{0.0, 0.0 + m_rect.y, 0.0, 0.0 + m_rect.height, m_bar.background_steps};
|
||||
@ -303,7 +313,12 @@ void renderer::fill_background() {
|
||||
*m_context << m_bar.background;
|
||||
}
|
||||
|
||||
m_context->paint();
|
||||
if (m_bar.radius != 0.0) {
|
||||
m_context->fill();
|
||||
} else {
|
||||
m_context->paint();
|
||||
}
|
||||
|
||||
m_context->restore();
|
||||
}
|
||||
|
||||
@ -311,8 +326,8 @@ void renderer::fill_background() {
|
||||
* Fill overline color
|
||||
*/
|
||||
void renderer::fill_overline(double x, double w) {
|
||||
if (m_bar.overline.size && m_attributes.test(static_cast<unsigned char>(attribute::OVERLINE))) {
|
||||
m_log.trace_x("renderer: overline(x=%i, w=%i)", x, w);
|
||||
if (m_bar.overline.size && m_attributes.test(static_cast<int>(attribute::OVERLINE))) {
|
||||
m_log.trace_x("renderer: overline(x=%f, w=%f)", x, w);
|
||||
m_context->save();
|
||||
*m_context << m_compositing_overline;
|
||||
*m_context << m_color_overline;
|
||||
@ -326,8 +341,8 @@ void renderer::fill_overline(double x, double w) {
|
||||
* Fill underline color
|
||||
*/
|
||||
void renderer::fill_underline(double x, double w) {
|
||||
if (m_bar.underline.size && m_attributes.test(static_cast<unsigned char>(attribute::UNDERLINE))) {
|
||||
m_log.trace_x("renderer: underline(x=%i, w=%i)", x, w);
|
||||
if (m_bar.underline.size && m_attributes.test(static_cast<int>(attribute::UNDERLINE))) {
|
||||
m_log.trace_x("renderer: underline(x=%f, w=%f)", x, w);
|
||||
m_context->save();
|
||||
*m_context << m_compositing_underline;
|
||||
*m_context << m_color_underline;
|
||||
@ -382,21 +397,15 @@ void renderer::fill_borders() {
|
||||
void renderer::draw_text(const string& contents) {
|
||||
m_log.trace_x("renderer: text(%s)", contents.c_str());
|
||||
|
||||
cairo_text_extents_t extents;
|
||||
cairo_text_extents(*m_context, contents.c_str(), &extents);
|
||||
|
||||
if (!extents.width) {
|
||||
return;
|
||||
}
|
||||
|
||||
cairo::abspos origin{static_cast<double>(m_rect.x), static_cast<double>(m_rect.y)};
|
||||
origin.y += m_rect.height / 2.0;
|
||||
|
||||
if (m_alignment == alignment::CENTER) {
|
||||
origin.x += m_rect.width / 2.0 - extents.width / 2.0;
|
||||
adjust_clickable_areas(extents.width / 2.0);
|
||||
origin.x += m_rect.width / 2.0;
|
||||
// adjust_clickable_areas(extents.width / 2.0);
|
||||
} else if (m_alignment == alignment::RIGHT) {
|
||||
origin.x += m_rect.width - extents.width;
|
||||
adjust_clickable_areas(extents.width);
|
||||
origin.x += m_rect.width;
|
||||
// adjust_clickable_areas(extents.width);
|
||||
} else {
|
||||
origin.x += m_x;
|
||||
}
|
||||
@ -410,24 +419,16 @@ void renderer::draw_text(const string& contents) {
|
||||
// m_context->restore();
|
||||
// }
|
||||
|
||||
origin.y += m_rect.height / 2.0;
|
||||
|
||||
m_context->save();
|
||||
*m_context << origin;
|
||||
*m_context << m_compositing_foreground;
|
||||
*m_context << m_color_foreground;
|
||||
*m_context << cairo::textblock{contents, m_fontindex};
|
||||
*m_context << cairo::textblock{m_alignment, contents, m_fontindex};
|
||||
m_context->position(&m_x, &m_y);
|
||||
m_context->restore();
|
||||
|
||||
// if (m_alignment == alignment::CENTER) {
|
||||
// m_x += extents.width / 2.0;
|
||||
// } else {
|
||||
// m_x += extents.width;
|
||||
// }
|
||||
|
||||
// fill_underline(origin.x, m_x - origin.x);
|
||||
// fill_overline(origin.x, m_x - origin.x);
|
||||
fill_underline(origin.x, m_x - origin.x);
|
||||
fill_overline(origin.x, m_x - origin.x);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -450,7 +451,7 @@ void renderer::highlight_clickable_areas() {
|
||||
map<alignment, int> hint_num{};
|
||||
for (auto&& action : m_actions) {
|
||||
if (!action.active) {
|
||||
unsigned char n = hint_num.find(action.align)->second++;
|
||||
int n = hint_num.find(action.align)->second++;
|
||||
double x = action.start_x + n * DEBUG_HINTS_OFFSET_X;
|
||||
double y = m_bar.pos.y + m_rect.y + n * DEBUG_HINTS_OFFSET_Y;
|
||||
double w = action.width();
|
||||
@ -513,27 +514,28 @@ bool renderer::on(const signals::parser::change_alignment& evt) {
|
||||
}
|
||||
|
||||
bool renderer::on(const signals::parser::offset_pixel& evt) {
|
||||
m_x += evt.cast();
|
||||
(void)evt;
|
||||
// m_x += evt.cast();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool renderer::on(const signals::parser::attribute_set& evt) {
|
||||
m_attributes.set(static_cast<unsigned char>(evt.cast()), true);
|
||||
m_attributes.set(static_cast<int>(evt.cast()), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool renderer::on(const signals::parser::attribute_unset& evt) {
|
||||
m_attributes.set(static_cast<unsigned char>(evt.cast()), false);
|
||||
m_attributes.set(static_cast<int>(evt.cast()), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool renderer::on(const signals::parser::attribute_toggle& evt) {
|
||||
m_attributes.flip(static_cast<unsigned char>(evt.cast()));
|
||||
m_attributes.flip(static_cast<int>(evt.cast()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool renderer::on(const signals::parser::action_begin& evt) {
|
||||
(void) evt;
|
||||
(void)evt;
|
||||
// auto a = evt.cast();
|
||||
// action_block action{};
|
||||
// action.button = a.button == mousebtn::NONE ? mousebtn::LEFT : a.button;
|
||||
@ -546,9 +548,9 @@ bool renderer::on(const signals::parser::action_begin& evt) {
|
||||
}
|
||||
|
||||
bool renderer::on(const signals::parser::action_end& evt) {
|
||||
(void) evt;
|
||||
(void)evt;
|
||||
// auto btn = evt.cast();
|
||||
// short int clickable_width = 0;
|
||||
// int clickable_width = 0;
|
||||
// for (auto action = m_actions.rbegin(); action != m_actions.rend(); action++) {
|
||||
// if (action->active && action->align == m_alignment && action->button == btn) {
|
||||
// switch (action->align) {
|
||||
|
@ -101,7 +101,7 @@ void tray_client::reconfigure(int x, int y) const {
|
||||
/**
|
||||
* Respond to client resize requests
|
||||
*/
|
||||
void tray_client::configure_notify(short int x, short int y) const {
|
||||
void tray_client::configure_notify(int x, int y) const {
|
||||
auto notify = memory_util::make_malloc_ptr<xcb_configure_notify_event_t, 32_z>();
|
||||
notify->response_type = XCB_CONFIGURE_NOTIFY;
|
||||
notify->event = m_window;
|
||||
|
Loading…
Reference in New Issue
Block a user