18#ifdef WITH_OPENGL_BACKEND
21#ifdef WITH_VULKAN_BACKEND
25#include <wayland-client-protocol.h>
27#ifdef WITH_OPENGL_BACKEND
28# ifdef WITH_GHOST_WAYLAND_DYNLOAD
31# include <wayland-egl.h>
36#ifdef WITH_GHOST_WAYLAND_LIBDECOR
37# ifdef WITH_GHOST_WAYLAND_DYNLOAD
42# ifdef WITH_VULKAN_BACKEND
48#include <fractional-scale-v1-client-protocol.h>
49#include <viewporter-client-protocol.h>
50#include <xdg-activation-v1-client-protocol.h>
51#include <xdg-decoration-unstable-v1-client-protocol.h>
52#include <xdg-shell-client-protocol.h>
74#ifdef USE_EVENT_BACKGROUND_THREAD
75# ifdef WITH_GHOST_WAYLAND_LIBDECOR
76# ifdef HAVE_MALLOC_USABLE_SIZE
77# define USE_LIBDECOR_CONFIG_COPY_WORKAROUND
87#ifdef USE_LIBDECOR_CONFIG_COPY_WORKAROUND
88# define USE_LIBDECOR_CONFIG_COPY_QUEUE
91#ifdef USE_LIBDECOR_CONFIG_COPY_WORKAROUND
92static libdecor_configuration *ghost_wl_libdecor_configuration_copy(
93 const libdecor_configuration *configuration);
94static void ghost_wl_libdecor_configuration_free(libdecor_configuration *configuration);
101#ifdef WITH_GHOST_WAYLAND_LIBDECOR
103# define use_libdecor GHOST_SystemWayland::use_libdecor_runtime()
106#ifdef WITH_GHOST_WAYLAND_LIBDECOR
107struct GWL_LibDecor_Window {
108 libdecor_frame *frame =
nullptr;
116 bool ack_configure =
false;
118 int size[2] = {0, 0};
119 libdecor_configuration *configuration =
nullptr;
121# ifdef USE_LIBDECOR_CONFIG_COPY_WORKAROUND
122 bool configuration_needs_free =
false;
125# ifdef USE_LIBDECOR_CONFIG_COPY_QUEUE
130 std::vector<libdecor_configuration *> configuration_queue;
136 bool initial_configure_seen =
false;
139static void gwl_libdecor_window_destroy(GWL_LibDecor_Window *decor)
141# ifdef USE_LIBDECOR_CONFIG_COPY_WORKAROUND
142 if (decor->pending.configuration_needs_free) {
143 ghost_wl_libdecor_configuration_free(decor->pending.configuration);
148# ifdef USE_LIBDECOR_CONFIG_COPY_QUEUE
149 for (libdecor_configuration *configuration : decor->pending.configuration_queue) {
150 ghost_wl_libdecor_configuration_free(configuration);
152 decor->pending.configuration_queue.clear();
164 enum zxdg_toplevel_decoration_v1_mode
mode = (
enum zxdg_toplevel_decoration_v1_mode)0;
188 xdg_toplevel_destroy(decor->
toplevel);
189 xdg_surface_destroy(decor->
surface);
199 GHOST_ASSERT(round_value > 0,
"Invalid rounding value!");
200 *value_p = (*value_p / round_value) * round_value;
205 GHOST_ASSERT(round_value > 0,
"Invalid rounding value!");
206 value_p[0] = (value_p[0] / round_value) * round_value;
207 value_p[1] = (value_p[1] / round_value) * round_value;
215 return value == ((value / round_value) * round_value);
240 return value * scale_params.
scale;
248 return value / scale_params.
scale;
295 bool can_invert_color)
299 const size_t bitmap_size =
sizeof(
uint8_t) * ((
size[0] + 7) / 8) *
size[1];
303 memcpy(ccs.
bitmap, bitmap, bitmap_size);
306 ccs.
mask =
static_cast<uint8_t *
>(malloc(bitmap_size));
307 memcpy(ccs.
mask,
mask, bitmap_size);
335#ifdef USE_EVENT_BACKGROUND_THREAD
358#ifdef USE_EVENT_BACKGROUND_THREAD
395# define PENDING_NUM (PENDING_WINDOW_CURSOR_SHAPE_REFRESH + 1)
449#ifdef WITH_OPENGL_BACKEND
450 wl_egl_window *egl_window =
nullptr;
452#ifdef WITH_VULKAN_BACKEND
469#ifdef WITH_GHOST_WAYLAND_LIBDECOR
470 GWL_LibDecor_Window *libdecor =
nullptr;
481#ifdef USE_EVENT_BACKGROUND_THREAD
504#ifdef USE_EVENT_BACKGROUND_THREAD
515#ifdef WITH_OPENGL_BACKEND
523#ifdef WITH_VULKAN_BACKEND
525 win->
backend.vulkan_window_info->size[0] =
size[0];
526 win->
backend.vulkan_window_info->size[1] =
size[1];
533#ifdef WITH_GHOST_WAYLAND_LIBDECOR
535 GWL_LibDecor_Window &decor = *win->libdecor;
542 xdg_toplevel_set_title(decor.
toplevel, title);
559#ifdef WITH_GHOST_WAYLAND_LIBDECOR
563static bool gwl_window_state_set_for_libdecor(libdecor_frame *frame,
570 switch (state_current) {
612 switch (state_current) {
614 xdg_toplevel_unset_maximized(toplevel);
618 xdg_toplevel_unset_fullscreen(toplevel);
627 xdg_toplevel_set_maximized(toplevel);
631 xdg_toplevel_set_minimized(toplevel);
635 xdg_toplevel_set_fullscreen(toplevel,
nullptr);
646#ifdef WITH_GHOST_WAYLAND_LIBDECOR
648 result = gwl_window_state_set_for_libdecor(win->libdecor->
frame,
state, state_current);
704 bool *r_surface_needs_commit,
705 bool *r_surface_needs_buffer_scale)
711 if (viewporter ==
nullptr) {
723 if (r_surface_needs_buffer_scale) {
724 *r_surface_needs_buffer_scale =
true;
730 if (r_surface_needs_commit) {
731 *r_surface_needs_commit =
true;
742 bool *r_surface_needs_commit,
743 bool *r_surface_needs_buffer_scale)
756 if (r_surface_needs_buffer_scale) {
757 *r_surface_needs_buffer_scale =
true;
763 if (r_surface_needs_commit) {
764 *r_surface_needs_commit =
true;
782 wp_viewport_set_destination(
805 if (
UNLIKELY(activation_manager ==
nullptr)) {
815 xdg_activation_token_v1_add_listener(
834 if (ghost_window_active) {
852 GWL_Window *win,
bool *r_surface_needs_commit,
bool *r_surface_needs_buffer_scale)
865 if (r_surface_needs_buffer_scale) {
866 *r_surface_needs_buffer_scale =
true;
871 if (r_surface_needs_commit) {
872 *r_surface_needs_commit =
true;
882 bool *r_surface_needs_commit,
883 bool *r_surface_needs_buffer_scale)
891 win, r_surface_needs_commit, r_surface_needs_buffer_scale);
895 bool *r_surface_needs_commit,
896 bool *r_surface_needs_resize_for_backend,
897 bool *r_surface_needs_buffer_scale)
910 win, r_surface_needs_commit, r_surface_needs_buffer_scale);
916 if (r_surface_needs_resize_for_backend) {
917 *r_surface_needs_resize_for_backend =
true;
931#ifdef USE_EVENT_BACKGROUND_THREAD
947 for (
size_t i = 0; i <
ARRAY_SIZE(actions); i++) {
980#ifdef USE_EVENT_BACKGROUND_THREAD
982 "Only from main thread!");
987 bool surface_needs_commit =
false;
988 bool surface_needs_resize_for_backend =
false;
989 bool surface_needs_buffer_scale =
false;
996 &surface_needs_commit,
997 &surface_needs_resize_for_backend,
998 &surface_needs_buffer_scale);
1004 win, &surface_needs_commit, &surface_needs_buffer_scale);
1009 surface_needs_buffer_scale =
true;
1013 if (surface_needs_resize_for_backend) {
1017 if (surface_needs_buffer_scale) {
1021#ifdef WITH_GHOST_WAYLAND_LIBDECOR
1023 GWL_LibDecor_Window &decor = *win->libdecor;
1024 if (decor.pending.ack_configure) {
1025 surface_needs_commit =
true;
1027 decor.pending.ack_configure =
false;
1031# ifdef USE_LIBDECOR_CONFIG_COPY_QUEUE
1032 GHOST_ASSERT(decor.pending.size[0] != 0 && decor.pending.size[1] != 0,
"Invalid size");
1033 for (libdecor_configuration *configuration : decor.pending.configuration_queue) {
1035 ghost_wl_libdecor_configuration_free(configuration);
1037 decor.pending.configuration_queue.clear();
1044 decor.pending.size[0] = 0;
1045 decor.pending.size[1] = 0;
1047 decor.initial_configure_seen =
true;
1049# ifdef USE_LIBDECOR_CONFIG_COPY_WORKAROUND
1050 if (decor.pending.configuration_needs_free) {
1051 ghost_wl_libdecor_configuration_free(decor.pending.configuration);
1052 decor.pending.configuration_needs_free =
false;
1056 decor.pending.configuration =
nullptr;
1067 surface_needs_commit =
true;
1076 if (surface_needs_commit) {
1077#ifdef USE_EVENT_BACKGROUND_THREAD
1105 "GHOST internal active state does not match WAYLAND!");
1120#ifdef USE_EVENT_BACKGROUND_THREAD
1150 if (scale_fractional_a < scale_fractional_b) {
1153 if (scale_fractional_a > scale_fractional_b) {
1162 int *r_scale_fractional)
1167 output_max = reg_output;
1172 if (r_scale_fractional) {
1177 return output_max->
scale;
1179 if (r_scale_fractional) {
1182 return scale_default;
1187 int *r_scale_fractional)
1191 if (!output_uniform) {
1192 output_uniform = reg_output;
1196 output_uniform =
nullptr;
1201 if (output_uniform) {
1202 if (r_scale_fractional) {
1207 return output_uniform->
scale;
1209 if (r_scale_fractional) {
1212 return scale_default;
1223#ifdef USE_LIBDECOR_CONFIG_COPY_WORKAROUND
1225static libdecor_configuration *ghost_wl_libdecor_configuration_copy(
1226 const libdecor_configuration *configuration)
1228 size_t configuration_size = malloc_usable_size((
void *)configuration);
1229 libdecor_configuration *configuration_copy = (libdecor_configuration *)malloc(
1230 configuration_size);
1231 memcpy((
void *)configuration_copy, (
const void *)configuration, configuration_size);
1232 return configuration_copy;
1235static void ghost_wl_libdecor_configuration_free(libdecor_configuration *configuration)
1237 free((
void *)configuration);
1249#define LOG (&LOG_WL_XDG_TOPLEVEL)
1258 CLOG_INFO(
LOG, 2,
"configure (size=[%d, %d])", width, height);
1262#ifdef USE_EVENT_BACKGROUND_THREAD
1267 for (
int i = 0; i < 2; i++) {
1281 enum xdg_toplevel_state *
state;
1284 case XDG_TOPLEVEL_STATE_MAXIMIZED:
1287 case XDG_TOPLEVEL_STATE_FULLSCREEN:
1290 case XDG_TOPLEVEL_STATE_ACTIVATED:
1314 CLOG_INFO(
LOG, 2,
"configure_bounds (size=[%d, %d])", width, height);
1352 xdg_activation_token_v1 *xdg_activation_token_v1,
1362 xdg_activation_v1_activate(activation_manager, token, win->
wl.
surface);
1385#define LOG (&LOG_WL_FRACTIONAL_SCALE)
1388 void *
data, wp_fractional_scale_v1 * ,
uint preferred_scale)
1390#ifdef USE_EVENT_BACKGROUND_THREAD
1391 std::lock_guard lock_frame_guard{
static_cast<GWL_Window *
>(
data)->frame_pending_mutex};
1395 "preferred_scale (preferred_scale=%.6f)",
1418#ifdef WITH_GHOST_WAYLAND_LIBDECOR
1420static CLG_LogRef LOG_WL_LIBDECOR_FRAME = {
"ghost.wl.handle.libdecor_frame"};
1421# define LOG (&LOG_WL_LIBDECOR_FRAME)
1423static void libdecor_frame_handle_configure(libdecor_frame *frame,
1424 libdecor_configuration *configuration,
1429# ifdef USE_EVENT_BACKGROUND_THREAD
1430 std::lock_guard lock_frame_guard{
static_cast<GWL_Window *
>(
data)->frame_pending_mutex};
1431 const bool is_main_thread = [
data] {
1441 int size_next[2] = {0, 0};
1450 "Fractional scale has no fractional component!");
1455 win->frame.buffer_scale;
1458 configuration, frame, &size_next[0], &size_next[1]))
1460 if (fractional_scale) {
1467 frame_pending.
size[0] = ((size_next[0] *
scale) * fractional_scale) / scale_as_fractional;
1468 frame_pending.
size[1] = ((size_next[1] *
scale) * fractional_scale) / scale_as_fractional;
1471 frame_pending.
size[0] = size_next[0] *
scale;
1472 frame_pending.
size[1] = size_next[1] *
scale;
1483 const GWL_LibDecor_Window &decor = *win->libdecor;
1484 size_next[0] = decor.pending.size[0];
1485 size_next[1] = decor.pending.size[1];
1491 enum libdecor_window_state window_state;
1493 frame_pending.
is_maximised = window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED;
1494 frame_pending.
is_fullscreen = window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN;
1495 frame_pending.
is_active = window_state & LIBDECOR_WINDOW_STATE_ACTIVE;
1501 GWL_LibDecor_Window &decor = *win->libdecor;
1503# ifdef USE_LIBDECOR_CONFIG_COPY_WORKAROUND
1505 if (decor.pending.configuration_needs_free) {
1506 ghost_wl_libdecor_configuration_free(decor.pending.configuration);
1507 decor.pending.configuration_needs_free =
false;
1511 decor.pending.size[0] = size_next[0];
1512 decor.pending.size[1] = size_next[1];
1513 decor.pending.configuration = configuration;
1514 decor.pending.ack_configure =
true;
1516# ifdef USE_EVENT_BACKGROUND_THREAD
1517 if (!is_main_thread) {
1518# ifdef USE_LIBDECOR_CONFIG_COPY_WORKAROUND
1519 decor.pending.configuration = ghost_wl_libdecor_configuration_copy(configuration);
1520 decor.pending.configuration_needs_free =
true;
1524 decor.pending.configuration =
nullptr;
1529# ifdef USE_LIBDECOR_CONFIG_COPY_QUEUE
1530 if (!(size_next[0] && size_next[1])) {
1532 if (decor.pending.configuration_needs_free ==
false) {
1533 decor.pending.configuration = ghost_wl_libdecor_configuration_copy(
1534 decor.pending.configuration);
1535 decor.pending.configuration_needs_free =
true;
1538 decor.pending.configuration_queue.push_back(decor.pending.configuration);
1539 decor.pending.configuration =
nullptr;
1540 decor.pending.configuration_needs_free =
false;
1542 decor.pending.ack_configure =
false;
1550# ifdef USE_EVENT_BACKGROUND_THREAD
1551 if (!is_main_thread) {
1562static void libdecor_frame_handle_close(libdecor_frame * ,
void *
data)
1571static void libdecor_frame_handle_commit(libdecor_frame * ,
void *
data)
1584static libdecor_frame_interface libdecor_frame_iface = {
1585 libdecor_frame_handle_configure,
1586 libdecor_frame_handle_close,
1587 libdecor_frame_handle_commit,
1601#define LOG (&LOG_WL_XDG_TOPLEVEL_DECORATION)
1604 void *
data, zxdg_toplevel_decoration_v1 * ,
const uint32_t mode)
1610 win->
xdg_decor->
mode = (zxdg_toplevel_decoration_v1_mode)mode;
1626#define LOG (&LOG_WL_XDG_SURFACE)
1629 xdg_surface *xdg_surface,
1640#ifdef USE_EVENT_BACKGROUND_THREAD
1641 std::lock_guard lock_frame_guard{
static_cast<GWL_Window *
>(
data)->frame_pending_mutex};
1646#ifdef USE_EVENT_BACKGROUND_THREAD
1648 const bool is_main_thread = system->
main_thread_id == std::this_thread::get_id();
1649 if (!is_main_thread) {
1674#define LOG (&LOG_WL_SURFACE)
1706#if defined(WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION) && \
1707 defined(WL_SURFACE_PREFERRED_BUFFER_TRANSFORM_SINCE_VERSION)
1708static void surface_handle_preferred_buffer_scale(
void * ,
1713 CLOG_INFO(
LOG, 2,
"handle_preferred_buffer_scale (factor=%d)", factor);
1716static void surface_handle_preferred_buffer_transform(
void * ,
1729#if defined(WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION) && \
1730 defined(WL_SURFACE_PREFERRED_BUFFER_TRANSFORM_SINCE_VERSION)
1731 surface_handle_preferred_buffer_scale,
1732 surface_handle_preferred_buffer_transform,
1755 const bool is_dialog,
1756 const bool stereoVisual,
1757 const bool exclusive,
1758 const bool is_debug,
1763 is_debug_context_(is_debug),
1764 preferred_device_(preferred_device)
1766#ifdef USE_EVENT_BACKGROUND_THREAD
1767 std::lock_guard lock_server_guard{*system->
server_mutex};
1770 window_->ghost_window =
this;
1771 window_->ghost_system = system;
1772 window_->ghost_context_type = type;
1793 int scale_fractional_from_output;
1795 system_->outputs_get(), 0, &scale_fractional_from_output);
1797 window_->frame.size[0] =
int32_t(width);
1798 window_->frame.size[1] =
int32_t(height);
1800 window_->is_dialog = is_dialog;
1803 window_->wl.surface = wl_compositor_create_surface(system_->wl_compositor_get());
1808 wp_fractional_scale_manager_v1 *fractional_scale_manager =
1810 if (fractional_scale_manager) {
1811 window_->wp.fractional_scale_handle = wp_fractional_scale_manager_v1_get_fractional_scale(
1812 fractional_scale_manager, window_->wl.surface);
1813 wp_fractional_scale_v1_add_listener(
1821 const int32_t size_min[2] = {320, 240};
1825#ifdef WITH_GHOST_WAYLAND_LIBDECOR
1827 window_->libdecor =
new GWL_LibDecor_Window;
1828 GWL_LibDecor_Window &decor = *window_->libdecor;
1832 system_->libdecor_context_get(), window_->wl.surface, &libdecor_frame_iface, window_);
1838 GWL_LibDecor_Window &decor_parent =
1848 decor.
surface = xdg_wm_base_get_xdg_surface(system_->xdg_decor_shell_get(),
1849 window_->wl.surface);
1853 xdg_toplevel_set_app_id(decor.
toplevel, xdg_app_id);
1858 if (parentWindow && is_dialog) {
1867#ifdef WITH_GHOST_WAYLAND_LIBDECOR
1875 wl_surface_set_user_data(window_->wl.surface,
this);
1881#ifdef WITH_GHOST_WAYLAND_LIBDECOR
1890 if (system_->xdg_decor_manager_get()) {
1891 decor.
toplevel_decor = zxdg_decoration_manager_v1_get_toplevel_decoration(
1892 system_->xdg_decor_manager_get(), decor.
toplevel);
1893 zxdg_toplevel_decoration_v1_add_listener(
1896 ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
1900 wl_surface_commit(window_->wl.surface);
1911 int early_buffer_scale = 0;
1912 int early_fractional_scale = 0;
1914 if (
const int test_fractional_scale =
1915 fractional_scale_manager ? (window_->frame_pending.fractional_scale_preferred ?
1916 window_->frame_pending.fractional_scale_preferred :
1917 scale_fractional_from_output) :
1921 early_fractional_scale = test_fractional_scale;
1926 early_fractional_scale = 0;
1929 else if (buffer_scale_from_output) {
1930 early_buffer_scale = buffer_scale_from_output;
1933 if (early_fractional_scale != 0) {
1936 window_->frame.fractional_scale_preferred = early_fractional_scale;
1937 window_->frame.fractional_scale = early_fractional_scale;
1938 window_->frame.buffer_scale = 1;
1940 window_->frame_pending.fractional_scale_preferred = early_fractional_scale;
1941 window_->frame_pending.fractional_scale = early_fractional_scale;
1942 window_->frame_pending.buffer_scale = 1;
1945 window_->frame_pending.is_scale_init =
true;
1948 bool surface_needs_commit_dummy =
false, surface_needs_buffer_scale_dummy =
false;
1950 window_, &surface_needs_commit_dummy, &surface_needs_buffer_scale_dummy);
1952 else if (early_buffer_scale != 0) {
1956 window_->frame.buffer_scale = early_buffer_scale;
1957 window_->frame_pending.buffer_scale = early_buffer_scale;
1960 window_->frame_pending.is_scale_init =
true;
1968 window_->frame.buffer_scale = 1;
1969 window_->frame_pending.buffer_scale = 1;
1970 GHOST_ASSERT(window_->frame_pending.is_scale_init ==
false,
1971 "An initialized scale is not expected");
1974 if (window_->frame_pending.is_scale_init) {
1977 "Fractional scale was not properly initialized");
1980 wl_surface_set_buffer_scale(window_->wl.surface, window_->frame.buffer_scale);
1984#ifdef WITH_GHOST_WAYLAND_LIBDECOR
1993 window_->frame.size[0] = std::min(window_->frame.size[0],
1995 window_->frame.size[1] = std::min(window_->frame.size[1],
2004#ifdef WITH_OPENGL_BACKEND
2005 if (type == GHOST_kDrawingContextTypeOpenGL) {
2007 window_->wl.surface,
int(window_->frame.size[0]),
int(window_->frame.size[1]));
2010#ifdef WITH_VULKAN_BACKEND
2011 if (type == GHOST_kDrawingContextTypeVulkan) {
2013 window_->backend.vulkan_window_info->
size[0] = window_->frame.size[0];
2014 window_->backend.vulkan_window_info->size[1] = window_->frame.size[1];
2022 GHOST_PRINT(
"Failed to create drawing context" << std::endl);
2025 window_->is_valid_setup =
true;
2028 if (window_->is_valid_setup ==
false) {
2033#ifdef WITH_GHOST_WAYLAND_LIBDECOR
2037 wl_surface_commit(window_->wl.surface);
2038 GWL_LibDecor_Window &decor = *window_->libdecor;
2046# ifdef WITH_VULKAN_BACKEND
2049 wl_buffer *dummy_buffer =
nullptr;
2050 if (window_->ghost_context_type == GHOST_kDrawingContextTypeVulkan) {
2052 const int format_size = 4;
2053 const int buffer_size = (window_->frame.size[0] * window_->frame.size[1]) * format_size;
2054 const int fd = memfd_create_sealed_for_vulkan_hack(
"ghost-wl-dummy-buffer");
2055 ftruncate(fd, buffer_size);
2056 wl_shm *shm = system_->wl_shm_get();
2057 wl_shm_pool *pool = wl_shm_create_pool(shm, fd, buffer_size);
2058 dummy_buffer = wl_shm_pool_create_buffer(pool,
2060 window_->frame.size[0],
2061 window_->frame.size[1],
2062 window_->frame.size[0] * format_size,
2064 wl_shm_pool_destroy(pool);
2066 wl_surface_attach(window_->wl.surface, dummy_buffer, 0, 0);
2067 wl_surface_damage(window_->wl.surface, 0, 0, window_->frame.size[0], window_->frame.size[1]);
2068 wl_surface_commit(window_->wl.surface);
2079# ifdef WITH_VULKAN_BACKEND
2080 if (window_->ghost_context_type == GHOST_kDrawingContextTypeVulkan) {
2081 wl_surface_attach(window_->wl.surface,
nullptr, 0, 0);
2082 wl_surface_commit(window_->wl.surface);
2083 wl_buffer_destroy(dummy_buffer);
2116 wl_surface_commit(window_->wl.surface);
2118 window_->is_init =
true;
2126#ifdef USE_EVENT_BACKGROUND_THREAD
2127 std::lock_guard lock_server_guard{*system_->server_mutex};
2132#ifdef WITH_OPENGL_BACKEND
2133 if (window_->ghost_context_type == GHOST_kDrawingContextTypeOpenGL) {
2137#ifdef WITH_VULKAN_BACKEND
2138 if (window_->ghost_context_type == GHOST_kDrawingContextTypeVulkan) {
2139 delete window_->backend.vulkan_window_info;
2143 if (window_->xdg.activation_token) {
2144 xdg_activation_token_v1_destroy(window_->xdg.activation_token);
2145 window_->xdg.activation_token =
nullptr;
2148 if (window_->wp.fractional_scale_handle) {
2149 wp_fractional_scale_v1_destroy(window_->wp.fractional_scale_handle);
2150 window_->wp.fractional_scale_handle =
nullptr;
2153 if (window_->wp.viewport) {
2154 wp_viewport_destroy(window_->wp.viewport);
2155 window_->wp.viewport =
nullptr;
2158#ifdef WITH_GHOST_WAYLAND_LIBDECOR
2160 gwl_libdecor_window_destroy(window_->libdecor);
2170 system_->window_surface_unref(window_->wl.surface);
2172 wl_surface_destroy(window_->wl.surface);
2184#ifdef USE_EVENT_BACKGROUND_THREAD
2187 GHOST_ASSERT(system_->main_thread_id == std::this_thread::get_id(),
"Only from main thread!");
2194 return system_->cursor_shape_check(cursorShape);
2199#ifdef USE_EVENT_BACKGROUND_THREAD
2200 std::lock_guard lock_server_guard{*system_->server_mutex};
2212 if (system_->window_cursor_grab_set(mode,
2217 window_->wl.surface,
2218 this->scale_params_get()))
2227#ifdef USE_EVENT_BACKGROUND_THREAD
2228 std::lock_guard lock_server_guard{*system_->server_mutex};
2232 system_->getWindowManager()->getActiveWindow());
2253 ok = system_->cursor_shape_check(shape);
2263#ifdef USE_EVENT_BACKGROUND_THREAD
2264 std::lock_guard lock_server_guard{*system_->server_mutex};
2266 return system_->cursor_grab_use_software_display_get(
m_cursorGrab);
2270 uint8_t *bitmap,
uint8_t *
mask,
int sizex,
int sizey,
int hotX,
int hotY,
bool canInvertColor)
2272#ifdef USE_EVENT_BACKGROUND_THREAD
2273 std::lock_guard lock_server_guard{*system_->server_mutex};
2277 system_->getWindowManager()->getActiveWindow());
2279 const int32_t hot_spot[2] = {hotX, hotY};
2282 window_->cursor_custom_shape, bitmap,
mask,
size, hot_spot, canInvertColor);
2308#ifdef USE_EVENT_BACKGROUND_THREAD
2309 std::lock_guard lock_server_guard{*system_->server_mutex};
2311 return system_->cursor_bitmap_get(bitmap);
2321#ifdef USE_EVENT_BACKGROUND_THREAD
2322 std::lock_guard lock_server_guard{*system_->server_mutex};
2330 return window_->title.empty() ?
"untitled" : window_->title;
2356#ifdef USE_EVENT_BACKGROUND_THREAD
2357 std::lock_guard lock_server_guard{*system_->server_mutex};
2358 std::lock_guard lock_frame_guard{window_->frame_pending_mutex};
2363 frame_pending.
size[0] = width;
2364 frame_pending.
size[1] = height;
2395 if (window_->frame.fractional_scale) {
2399 return window_->frame.buffer_scale *
base_dpi;
2404#ifdef USE_EVENT_BACKGROUND_THREAD
2405 std::lock_guard lock_server_guard{*system_->server_mutex};
2407 const GHOST_TSuccess ok = system_->cursor_visibility_set(visible);
2417#ifdef USE_EVENT_BACKGROUND_THREAD
2418 std::lock_guard lock_server_guard{*system_->server_mutex};
2425#ifdef USE_EVENT_BACKGROUND_THREAD
2426 std::lock_guard lock_server_guard{*system_->server_mutex};
2451#ifdef USE_EVENT_BACKGROUND_THREAD
2452 std::lock_guard lock_server_guard{*system_->server_mutex};
2455#ifdef WITH_GHOST_WAYLAND_LIBDECOR
2462 xdg_toplevel_set_fullscreen(window_->xdg_decor->toplevel,
nullptr);
2470#ifdef USE_EVENT_BACKGROUND_THREAD
2471 std::lock_guard lock_server_guard{*system_->server_mutex};
2474#ifdef WITH_GHOST_WAYLAND_LIBDECOR
2481 xdg_toplevel_unset_fullscreen(window_->xdg_decor->toplevel);
2488 return window_->is_dialog;
2499#ifdef WITH_VULKAN_BACKEND
2500 case GHOST_kDrawingContextTypeVulkan: {
2502 GHOST_kVulkanPlatformWayland,
2505 window_->wl.surface,
2506 system_->wl_display_get(),
2507 window_->backend.vulkan_window_info,
2512 if (
context->initializeDrawingContext()) {
2520#ifdef WITH_OPENGL_BACKEND
2521 case GHOST_kDrawingContextTypeOpenGL: {
2522 for (
int minor = 6; minor >= 3; --minor) {
2523 GHOST_Context *
context =
new GHOST_ContextEGL(
2526 EGLNativeWindowType(window_->backend.egl_window),
2527 EGLNativeDisplayType(system_->wl_display_get()),
2528 EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
2532 (is_debug_context_ ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
2536 if (
context->initializeDrawingContext()) {
2551#ifdef WITH_INPUT_IME
2555 system_->ime_begin(
this,
x,
y,
w, h, completed);
2558void GHOST_WindowWayland::endIME()
2560 system_->ime_end(
this);
2575 return window_->frame.buffer_scale;
2583 scale_params->
is_fractional = (window_->frame.fractional_scale != 0);
2584 scale_params->
scale = scale_params->
is_fractional ? window_->frame.fractional_scale :
2585 window_->frame.buffer_scale;
2586 return *scale_params;
2591 if (window_->frame.fractional_scale) {
2594 return value / window_->frame.buffer_scale;
2599 if (window_->frame.fractional_scale) {
2602 return value * window_->frame.buffer_scale;
2607 return window_->wl.surface;
2612 return window_->outputs;
2625 return system_->pushEvent_maybe_pending(
2631#ifdef USE_EVENT_BACKGROUND_THREAD
2632 const bool is_main_thread = system_->main_thread_id == std::this_thread::get_id();
2638 if (window_->is_init) {
2639 if (system_->getWindowManager()->setActiveWindow(
this) ==
GHOST_kFailure) {
2646#ifdef WITH_GHOST_WAYLAND_LIBDECOR
2659#ifdef USE_EVENT_BACKGROUND_THREAD
2661 const bool is_main_thread = system_->main_thread_id == std::this_thread::get_id();
2666 if (window_->is_init) {
2667 system_->getWindowManager()->setWindowInactive(
this);
2672#ifdef WITH_GHOST_WAYLAND_LIBDECOR
2685 return system_->pushEvent_maybe_pending(
2693 return system_->pushEvent_maybe_pending(
2707#ifdef USE_EVENT_BACKGROUND_THREAD
2708 if (system_->main_thread_id != std::this_thread::get_id()) {
2718#ifdef USE_EVENT_BACKGROUND_THREAD
2730#ifdef USE_EVENT_BACKGROUND_THREAD
2731 if (system_->main_thread_id != std::this_thread::get_id()) {
2736 int fractional_scale_next = -1;
2737 int fractional_scale_from_output = 0;
2745#ifdef USE_EVENT_BACKGROUND_THREAD
2746 std::lock_guard lock_frame_guard{window_->frame_pending_mutex};
2749 if (window_->wp.fractional_scale_handle) {
2752 if (window_->frame_pending.fractional_scale_preferred != 0) {
2753 fractional_scale_next = window_->frame_pending.fractional_scale_preferred;
2758 if (fractional_scale_next == -1) {
2759 fractional_scale_next = fractional_scale_from_output;
2763 bool changed =
false;
2765 const bool is_fractional_prev = window_->frame.fractional_scale != 0;
2769 window_->frame_pending.fractional_scale = is_fractional_next ? fractional_scale_next : 0;
2770 window_->frame_pending.buffer_scale = is_fractional_next ?
2774 const int fractional_scale_prev = window_->frame.fractional_scale ?
2775 window_->frame.fractional_scale :
2780 bool do_frame_resize =
false;
2781 bool do_frame_update =
false;
2783 if (window_->frame_pending.is_scale_init ==
false) {
2784 window_->frame_pending.is_scale_init =
true;
2793#ifdef WITH_GHOST_WAYLAND_LIBDECOR
2802 int size_next[2] = {0, 0};
2803 int size_orig[2] = {0, 0};
2806 for (
size_t i = 0; i <
ARRAY_SIZE(window_->frame_pending.size); i++) {
2807 const int value = size_next[i] ? window_->frame_pending.size[i] : window_->frame.size[i];
2808 size_orig[i] = value;
2809 if (is_fractional_prev || is_fractional_next) {
2811 double(fractional_scale_next));
2814 size_next[i] = value / scale_prev;
2816 if (window_->frame_pending.buffer_scale > 1) {
2821 if (size_orig[0] != size_next[0] || size_orig[1] != size_next[1]) {
2822 GWL_LibDecor_Window &decor = *window_->libdecor;
2830 do_frame_resize =
false;
2831 do_frame_update =
true;
2835 if ((fractional_scale_prev != fractional_scale_next) ||
2836 (window_->frame_pending.buffer_scale != window_->frame.buffer_scale))
2838 do_frame_resize =
true;
2842 if (do_frame_resize) {
2849 for (
size_t i = 0; i <
ARRAY_SIZE(window_->frame_pending.size); i++) {
2850 const int value = window_->frame_pending.size[i] ? window_->frame_pending.size[i] :
2851 window_->frame.size[i];
2852 if (is_fractional_prev || is_fractional_next) {
2853 window_->frame_pending.size[i] = lroundf((value *
double(fractional_scale_next)) /
2854 double(fractional_scale_prev));
2857 window_->frame_pending.size[i] = (value * scale_next) / scale_prev;
2859 if (window_->frame_pending.buffer_scale > 1) {
2860 gwl_round_int_by(&window_->frame_pending.size[i], window_->frame_pending.buffer_scale);
2863 do_frame_update =
true;
2866 if (do_frame_update) {
2876 std::vector<GWL_Output *> &
outputs = window_->outputs;
2887 std::vector<GWL_Output *> &
outputs = window_->outputs;
2896#ifdef USE_EVENT_BACKGROUND_THREAD
2904 "Run from main thread!");
KDTree *BLI_kdtree_nd_ new(unsigned int nodes_len_capacity)
void BLI_kdtree_nd_ free(KDTree *tree)
#define CLOG_INFO(clg_ref, level,...)
#define GHOST_OPENGL_EGL_CONTEXT_FLAGS
#define GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY
#define GHOST_ASSERT(x, info)
GWL_Output * ghost_wl_output_user_data(wl_output *wl_output)
void ghost_wl_surface_tag(wl_surface *wl_surface)
bool ghost_wl_display_report_error_if_set(wl_display *display)
bool ghost_wl_output_own(const wl_output *wl_output)
#define FRACTIONAL_DENOMINATOR
@ GHOST_kWindowStateMinimized
@ GHOST_kWindowStateMaximized
@ GHOST_kWindowStateNormal
@ GHOST_kWindowStateFullScreen
@ GHOST_kStandardCursorCustom
@ GHOST_kStandardCursorDefault
@ GHOST_kEventWindowClose
@ GHOST_kEventWindowActivate
@ GHOST_kEventWindowUpdateDecor
@ GHOST_kEventWindowDeactivate
@ GHOST_kEventWindowDPIHintChanged
GHOST_TDrawingContextType
@ GHOST_kDrawingContextTypeNone
#define WL_ARRAY_FOR_EACH(pos, array)
static void wp_fractional_scale_handle_preferred_scale(void *data, wp_fractional_scale_v1 *, uint preferred_scale)
wl_fixed_t gwl_window_scale_wl_fixed_to(const GWL_WindowScaleParams &scale_params, wl_fixed_t value)
eGWL_PendingWindowActions
@ PENDING_WINDOW_FRAME_CONFIGURE
@ PENDING_OUTPUT_SCALE_UPDATE_DEFERRED
@ PENDING_WINDOW_CURSOR_SHAPE_REFRESH
@ PENDING_WINDOW_SURFACE_COMMIT
@ PENDING_OUTPUT_SCALE_UPDATE
wl_fixed_t gwl_window_scale_wl_fixed_from(const GWL_WindowScaleParams &scale_params, wl_fixed_t value)
static void gwl_round_int2_by(int value_p[2], const int round_value)
static int gwl_window_fractional_from_viewport(const GWL_WindowFrame &frame, int value)
static void surface_handle_leave(void *data, wl_surface *, wl_output *wl_output)
static void gwl_window_frame_pending_fractional_scale_set_notest(GWL_Window *win, bool *r_surface_needs_commit, bool *r_surface_needs_buffer_scale)
static CLG_LogRef LOG_WL_XDG_TOPLEVEL_DECORATION
static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win)
int gwl_window_scale_int_to(const GWL_WindowScaleParams &scale_params, int value)
static bool gwl_window_viewport_unset(GWL_Window *win, bool *r_surface_needs_commit, bool *r_surface_needs_buffer_scale)
static void gwl_window_cursor_custom_free(GWL_WindowCursorCustomShape &ccs)
static GHOST_TWindowState gwl_window_state_get(const GWL_Window *win)
static void xdg_toplevel_handle_configure(void *data, xdg_toplevel *, const int32_t width, const int32_t height, wl_array *states)
static CLG_LogRef LOG_WL_XDG_SURFACE
static void gwl_window_frame_pending_fractional_scale_set(GWL_Window *win, bool *r_surface_needs_commit, bool *r_surface_needs_buffer_scale)
static void xdg_surface_handle_configure(void *data, xdg_surface *xdg_surface, const uint32_t serial)
static void gwl_window_frame_update_from_pending(GWL_Window *win)
static const wp_fractional_scale_v1_listener wp_fractional_scale_listener
static CLG_LogRef LOG_WL_SURFACE
static const xdg_toplevel_listener xdg_toplevel_listener
static const zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_v1_listener
static GHOST_TSuccess gwl_window_cursor_custom_load(const GWL_WindowCursorCustomShape &ccs, GHOST_SystemWayland *system)
static bool gwl_window_state_set(GWL_Window *win, const GHOST_TWindowState state)
static GHOST_TSuccess gwl_window_cursor_shape_refresh(GHOST_TStandardCursor shape, const GWL_WindowCursorCustomShape &ccs, GHOST_SystemWayland *system)
static void gwl_window_frame_pending_size_set(GWL_Window *win, bool *r_surface_needs_commit, bool *r_surface_needs_resize_for_backend, bool *r_surface_needs_buffer_scale)
static bool gwl_window_state_set_for_xdg(xdg_toplevel *toplevel, const GHOST_TWindowState state, const GHOST_TWindowState state_current)
static int outputs_uniform_scale_or_default(const std::vector< GWL_Output * > &outputs, const int32_t scale_default, int *r_scale_fractional)
static void gwl_xdg_decor_window_destroy(GWL_XDG_Decor_Window *decor)
int gwl_window_scale_int_from(const GWL_WindowScaleParams &scale_params, int value)
static CLG_LogRef LOG_WL_FRACTIONAL_SCALE
static void xdg_toplevel_handle_configure_bounds(void *data, xdg_toplevel *, int32_t width, int32_t height)
static int gwl_window_fractional_to_viewport(const GWL_WindowFrame &frame, int value)
static void gwl_window_activate(GWL_Window *win)
static void gwl_window_resize_for_backend(GWL_Window *win, const int32_t size[2])
static int outputs_max_scale_or_default(const std::vector< GWL_Output * > &outputs, const int32_t scale_default, int *r_scale_fractional)
static constexpr size_t base_dpi
static void gwl_window_cursor_custom_clear(GWL_WindowCursorCustomShape &ccs)
static void gwl_window_pending_actions_handle(GWL_Window *win)
static const xdg_surface_listener xdg_surface_listener
static int gwl_window_fractional_to_viewport_round(const GWL_WindowFrame &frame, int value)
static int output_scale_cmp(const GWL_Output *output_a, const GWL_Output *output_b)
static void gwl_round_int_by(int *value_p, const int round_value)
static CLG_LogRef LOG_WL_XDG_TOPLEVEL
static void gwl_window_cursor_custom_store(GWL_WindowCursorCustomShape &ccs, const uint8_t *bitmap, const uint8_t *mask, const int32_t size[2], const int32_t hot_spot[2], bool can_invert_color)
static bool gwl_window_viewport_size_update(GWL_Window *win)
static void xdg_activation_handle_done(void *data, xdg_activation_token_v1 *xdg_activation_token_v1, const char *token)
static const xdg_activation_token_v1_listener xdg_activation_listener
static void xdg_toplevel_handle_wm_capabilities(void *, xdg_toplevel *, wl_array *)
static void gwl_window_pending_actions_tag(GWL_Window *win, enum eGWL_PendingWindowActions type)
static void surface_handle_enter(void *data, wl_surface *, wl_output *wl_output)
static bool gwl_round_int_test(int value, const int round_value)
static bool gwl_window_viewport_set(GWL_Window *win, bool *r_surface_needs_commit, bool *r_surface_needs_buffer_scale)
static void gwl_window_title_set(GWL_Window *win, const char *title)
static int gwl_window_fractional_from_viewport_round(const GWL_WindowFrame &frame, int value)
static void xdg_toplevel_decoration_handle_configure(void *data, zxdg_toplevel_decoration_v1 *, const uint32_t mode)
static const xdg_activation_token_v1_listener * xdg_activation_listener_get()
static const wl_surface_listener wl_surface_listener
static void xdg_toplevel_handle_close(void *data, xdg_toplevel *)
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
static const char * xdg_app_id_get()
uint64_t getMilliSeconds() const override
std::thread::id main_thread_id
struct wl_display * wl_display_get()
struct wp_fractional_scale_manager_v1 * wp_fractional_scale_manager_get()
GHOST_TSuccess cursor_shape_set(GHOST_TStandardCursor shape)
struct wp_viewporter * wp_viewporter_get()
struct wl_seat * wl_seat_active_get_with_input_serial(uint32_t &serial)
GHOST_TSuccess cursor_shape_custom_set(const uint8_t *bitmap, const uint8_t *mask, int sizex, int sizey, int hotX, int hotY, bool canInvertColor)
std::atomic< bool > has_pending_actions_for_window
std::mutex * server_mutex
struct xdg_activation_v1 * xdg_activation_manager_get()
GHOST_WindowManager * getWindowManager() const
GHOST_TSuccess pushEvent(const GHOST_IEvent *event)
GHOST_IWindow * getActiveWindow() const
GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor cursorShape) override
const struct GWL_WindowScaleParams & scale_params_get() const
GHOST_TSuccess setClientSize(uint32_t width, uint32_t height) override
bool outputs_leave(GWL_Output *output)
GHOST_TSuccess setClientWidth(uint32_t width) override
wl_fixed_t wl_fixed_to_window(wl_fixed_t value) const
GHOST_TSuccess setOrder(GHOST_TWindowOrder order) override
GHOST_TSuccess swapBuffers() override
GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode) override
GHOST_TSuccess notify_size()
void outputs_changed_update_scale_tag()
GHOST_TSuccess setState(GHOST_TWindowState state) override
GHOST_TSuccess setWindowCursorVisibility(bool visible) override
GHOST_TWindowState getState() const override
bool getCursorGrabUseSoftwareDisplay() override
GHOST_TSuccess beginFullScreen() const override
bool isDialog() const override
struct wl_surface * wl_surface_get() const
GHOST_TSuccess notify_decor_redraw()
bool getValid() const override
wl_fixed_t wl_fixed_from_window(wl_fixed_t value) const
std::string getTitle() const override
GHOST_TSuccess deactivate()
bool outputs_changed_update_scale()
void getClientBounds(GHOST_Rect &bounds) const override
GHOST_TSuccess activate()
uint16_t getDPIHint() override
void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const override
GHOST_TSuccess endFullScreen() const override
GHOST_TSuccess setClientHeight(uint32_t height) override
GHOST_TSuccess cursor_shape_refresh()
void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const override
bool outputs_enter(GWL_Output *output)
const void pending_actions_handle()
~GHOST_WindowWayland() override
GHOST_TSuccess invalidate() override
GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape) override
void setTitle(const char *title) override
GHOST_WindowWayland(GHOST_SystemWayland *system, const char *title, int32_t left, int32_t top, uint32_t width, uint32_t height, GHOST_TWindowState state, const GHOST_IWindow *parentWindow, GHOST_TDrawingContextType type, const bool is_dialog, const bool stereoVisual, const bool exclusive, const bool is_debug, const GHOST_GPUDevice &preferred_device)
GHOST_TSuccess setWindowCustomCursorShape(uint8_t *bitmap, uint8_t *mask, int sizex, int sizey, int hotX, int hotY, bool canInvertColor) override
void getWindowBounds(GHOST_Rect &bounds) const override
GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap) override
const std::vector< GWL_Output * > & outputs_get()
GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) const override
GHOST_TGrabCursorMode m_cursorGrab
int32_t m_cursorGrabInitPos[2]
GHOST_TStandardCursor getCursorShape() const override
GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type) override
GHOST_TStandardCursor m_cursorShape
GHOST_TSuccess setSwapInterval(int interval) override
GHOST_TSuccess releaseNativeHandles()
GHOST_TAxisFlag m_cursorGrabAxis
virtual GHOST_TSuccess swapBuffers() override
GHOST_Window(uint32_t width, uint32_t height, GHOST_TWindowState state, const bool wantStereoVisual=false, const bool exclusive=false)
virtual bool getValid() const override
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
ccl_device_inline float4 mask(const int4 mask, const float4 a)
int context(const bContext *C, const char *member, bContextDataResult *result)
MatBase< T, NumCol, NumRow > scale(const MatBase< T, NumCol, NumRow > &mat, const VectorT &scale)
static blender::bke::bNodeSocketTemplate outputs[]
bool has_scale_fractional
int fractional_scale_preferred
GHOST_SystemWayland * ghost_system
std::atomic< bool > pending_actions[PENDING_NUM]
wp_fractional_scale_v1 * fractional_scale_handle
GWL_XDG_Decor_Window * xdg_decor
struct GWL_Window::@143205252035253113000336061374126142163150227005 xdg
struct GWL_Window::@042173167354306054241173206346352303252015214025 backend
GWL_WindowScaleParams scale_params
xdg_activation_token_v1 * activation_token
std::mutex frame_pending_mutex
struct GWL_Window::@062213271335146055326336310227020053332051114372 wl
GWL_WindowFrame frame_pending
struct GWL_Window::@343105174160036336307132323142065247264353321221 wp
GHOST_WindowWayland * ghost_window
GWL_WindowCursorCustomShape cursor_custom_shape
std::vector< GWL_Output * > outputs
GHOST_TDrawingContextType ghost_context_type
zxdg_toplevel_decoration_v1 * toplevel_decor
uint32_t ack_configure_serial
enum zxdg_toplevel_decoration_v1_mode mode
bool initial_configure_seen
struct GWL_XDG_Decor_Window::@047262162032150100374334251367135021075004103132 pending
#define wl_display_dispatch(...)
#define wl_display_flush(...)
#define wl_display_roundtrip(...)
#define wl_egl_window_resize(...)
#define wl_egl_window_create(...)
#define wl_egl_window_destroy(...)
#define libdecor_frame_set_fullscreen(...)
#define libdecor_frame_map(...)
#define libdecor_state_new(...)
#define libdecor_frame_unset_fullscreen(...)
#define libdecor_configuration_get_content_size(...)
#define libdecor_state_free(...)
#define libdecor_configuration_get_window_state(...)
#define libdecor_frame_unref(...)
#define libdecor_frame_unset_maximized(...)
#define libdecor_frame_get_xdg_toplevel(...)
#define libdecor_frame_set_app_id(...)
#define libdecor_frame_set_min_content_size(...)
#define libdecor_frame_set_parent(...)
#define libdecor_frame_set_title(...)
#define libdecor_frame_set_minimized(...)
#define libdecor_frame_commit(...)
#define libdecor_decorate(...)
#define libdecor_frame_set_maximized(...)