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:
Campbell Barton
2023-12-13 10:00:09 +11:00
parent 46a9530a75
commit 6e0037e54d
2 changed files with 46 additions and 15 deletions
+46 -7
View File
@@ -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__)