Fix #115878: build error with LIBDECOR & WITH_GHOST_WAYLAND_DYNLOAD=OFF
There were two problems here: - libdecor_frame_get_content_* is not available in LIBDECOR v0.1.0. - These functions aren't exposed by <libdecor.h>, they're only exposed by `libdecor-plugin.h` (intended for plug-ins that implement window decorations). Resolve by storing the last applied size from LIBDECOR for reuse.
This commit is contained in:
@@ -65,6 +65,18 @@ static constexpr size_t base_dpi = 96;
|
||||
struct WGL_LibDecor_Window {
|
||||
libdecor_frame *frame = nullptr;
|
||||
|
||||
/**
|
||||
* Store the last size applied from #libdecor_frame_interface::configure
|
||||
* This is meant to be equivalent of calling:
|
||||
* `libdecor_frame_get_content_width(frame)`
|
||||
* `libdecor_frame_get_content_height(frame)`
|
||||
* However these functions are only available via the plugin API,
|
||||
* so they need to be stored somewhere.
|
||||
*/
|
||||
struct {
|
||||
int32_t size[2] = {0, 0};
|
||||
} applied;
|
||||
|
||||
/**
|
||||
* Used at startup to set the initial window size
|
||||
* (before fractional scale information is available).
|
||||
@@ -73,6 +85,8 @@ struct WGL_LibDecor_Window {
|
||||
|
||||
/** The window has been configured (see #xdg_surface_ack_configure). */
|
||||
bool initial_configure_seen = false;
|
||||
/** The window size has been configured. */
|
||||
bool initial_configure_seen_with_size = false;
|
||||
/** The window state has been configured. */
|
||||
bool initial_state_seen = false;
|
||||
};
|
||||
@@ -1153,12 +1167,21 @@ static void libdecor_frame_handle_configure(libdecor_frame *frame,
|
||||
GWL_WindowFrame *frame_pending = &static_cast<GWL_Window *>(data)->frame_pending;
|
||||
|
||||
/* Set the size. */
|
||||
int size_decor[2] = {
|
||||
libdecor_frame_get_content_width(frame),
|
||||
libdecor_frame_get_content_height(frame),
|
||||
};
|
||||
int size_next[2] = {0, 0};
|
||||
bool has_size = false;
|
||||
|
||||
/* Keep track the current size of window decorations (last set by this function). */
|
||||
int size_decor[2] = {0, 0};
|
||||
|
||||
{
|
||||
const GWL_Window *win = static_cast<GWL_Window *>(data);
|
||||
const WGL_LibDecor_Window &decor = *win->libdecor;
|
||||
if (decor.initial_configure_seen_with_size) {
|
||||
size_decor[0] = decor.applied.size[0];
|
||||
size_decor[1] = decor.applied.size[1];
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
GWL_Window *win = static_cast<GWL_Window *>(data);
|
||||
const int fractional_scale = win->frame.fractional_scale ?
|
||||
@@ -1259,12 +1282,21 @@ static void libdecor_frame_handle_configure(libdecor_frame *frame,
|
||||
GWL_Window *win = static_cast<GWL_Window *>(data);
|
||||
WGL_LibDecor_Window &decor = *win->libdecor;
|
||||
if (has_size == false) {
|
||||
/* Keep the current decor size. */
|
||||
size_next[0] = size_decor[0];
|
||||
size_next[1] = size_decor[1];
|
||||
}
|
||||
libdecor_state *state = libdecor_state_new(UNPACK2(size_next));
|
||||
libdecor_frame_commit(frame, state, configuration);
|
||||
libdecor_state_free(state);
|
||||
else {
|
||||
/* Store the new size for later reuse. */
|
||||
decor.applied.size[0] = size_next[0];
|
||||
decor.applied.size[1] = size_next[1];
|
||||
}
|
||||
|
||||
if (size_next[0] && size_next[1]) {
|
||||
libdecor_state *state = libdecor_state_new(UNPACK2(size_next));
|
||||
libdecor_frame_commit(frame, state, configuration);
|
||||
libdecor_state_free(state);
|
||||
}
|
||||
|
||||
/* Only ever use this once, after initial creation:
|
||||
* #wp_fractional_scale_v1_listener::preferred_scale provides fractional scaling values. */
|
||||
@@ -1278,6 +1310,13 @@ static void libdecor_frame_handle_configure(libdecor_frame *frame,
|
||||
decor.initial_state_seen = true;
|
||||
}
|
||||
}
|
||||
if (decor.initial_configure_seen_with_size == false) {
|
||||
if (is_main_thread) {
|
||||
if (size_next[0] && size_next[1]) {
|
||||
decor.initial_configure_seen_with_size = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ WAYLAND_DYNLOAD_FN(libdecor_configuration_get_window_state)
|
||||
WAYLAND_DYNLOAD_FN(libdecor_decorate)
|
||||
WAYLAND_DYNLOAD_FN(libdecor_dispatch)
|
||||
WAYLAND_DYNLOAD_FN(libdecor_frame_commit)
|
||||
WAYLAND_DYNLOAD_FN(libdecor_frame_get_content_height)
|
||||
WAYLAND_DYNLOAD_FN(libdecor_frame_get_content_width)
|
||||
WAYLAND_DYNLOAD_FN(libdecor_frame_get_xdg_toplevel)
|
||||
WAYLAND_DYNLOAD_FN(libdecor_frame_map)
|
||||
WAYLAND_DYNLOAD_FN(libdecor_frame_set_app_id)
|
||||
@@ -78,8 +76,6 @@ struct WaylandDynload_Libdecor {
|
||||
void WL_DYN_FN(libdecor_frame_commit)(struct libdecor_frame *frame,
|
||||
struct libdecor_state *state,
|
||||
struct libdecor_configuration *configuration);
|
||||
int WL_DYN_FN(libdecor_frame_get_content_width)(struct libdecor_frame *frame);
|
||||
int WL_DYN_FN(libdecor_frame_get_content_height)(struct libdecor_frame *frame);
|
||||
struct xdg_toplevel *WL_DYN_FN(libdecor_frame_get_xdg_toplevel)(struct libdecor_frame *frame);
|
||||
void WL_DYN_FN(libdecor_frame_map)(struct libdecor_frame *frame);
|
||||
void WL_DYN_FN(libdecor_frame_set_app_id)(struct libdecor_frame *frame, const char *app_id);
|
||||
@@ -116,10 +112,6 @@ struct WaylandDynload_Libdecor {
|
||||
# define libdecor_dispatch(...) (*wayland_dynload_libdecor.libdecor_dispatch)(__VA_ARGS__)
|
||||
# define libdecor_frame_commit(...) \
|
||||
(*wayland_dynload_libdecor.libdecor_frame_commit)(__VA_ARGS__)
|
||||
# define libdecor_frame_get_content_height(...) \
|
||||
(*wayland_dynload_libdecor.libdecor_frame_get_content_height)(__VA_ARGS__)
|
||||
# define libdecor_frame_get_content_width(...) \
|
||||
(*wayland_dynload_libdecor.libdecor_frame_get_content_width)(__VA_ARGS__)
|
||||
# define libdecor_frame_get_xdg_toplevel(...) \
|
||||
(*wayland_dynload_libdecor.libdecor_frame_get_xdg_toplevel)(__VA_ARGS__)
|
||||
# define libdecor_frame_map(...) (*wayland_dynload_libdecor.libdecor_frame_map)(__VA_ARGS__)
|
||||
|
||||
Reference in New Issue
Block a user