[wayland_libdecor_egl] set_min_content_size

main
Allen Webster 2026-02-20 13:29:40 -08:00
parent 197708e186
commit b116b0ffd7
1 changed files with 22 additions and 143 deletions

View File

@ -16,53 +16,7 @@ exit 0
** headers and example code.
*/
/* [1] IMPORTANT NOTE
**
** (1) /ch04.html#sect-Protocol-Code-Generation
** " The interfaces, requests and events are defined in
** protocol/wayland.xml. This xml is used to generate the function
** prototypes that can be used by clients and compositors. "
**
** (1) /ch04.html#sect-Protocol-Basic-Principles
** " The Wayland protocol is an asynchronous object oriented protocol.
** All requests are method invocations on some object.
** ...
** The protocol is message-based. A message sent by a client to
** the server is called request. A message from the server to a
** client is called event. "
**
**~
**~ I have yet to see any place where it is *defined* how the xml
**~ is transformed into function prototypes. So I'm putting notes of
**~ my own inferences here.
**~
**~ From the client's perspective:
**~
**~ A request `R(...)` on an object interface `O` becomes the
**~ function `O_R(O *obj, ...)`.
**~ ! Sometimes the arguments for `R(...)` include an argument that
**~ doesn't appear to have a documented type (at least in (1)).
**~ We can also refer to the xml and see such arguments have
**~ the type "new_id". These seem to actually be a return value
**~ that does not appear in the generated signature as an id,
**~ but instead is translated into a typed return pointer.
**~ If the documentation does explicitly write the "new_id" type
**~ that also gets rewritten to a typed return.
**~
**~ An event `E(...)` on an object interface `O` will becomes a
**~ callback with the signature `(*)(void *data, O *obj, ...)`.
**~
**~ The collection of event callbacks on an object interface become
**~ `struct wl_O_listener` using the names `E` of the events as the
**~ field names.
**~
**~ A function for adding the listener to the object is also generated
**~ `wl_O_add_listener(O *obj, struct wl_O_listener *listener, void *data)`
**~
**~ Each object interface `O` becomes a `wl_O_interface` which (I think)
**~ is a global variable vtable representation of the interface.
**~
*/
/* [1] IMPORTANT NOTE @see([1] in wayland_xdg_egl.c) */
#include <wayland-client.h>
#include <libdecor.h>
@ -113,91 +67,6 @@ typedef struct Ctx{
static Ctx ctx = {0};
#if 0
/* (2) xdg_wm_base::ping */
static void
wlevent__xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base,
uint32_t serial){
xdg_wm_base_pong(xdg_wm_base, serial);
}
const struct xdg_wm_base_listener xdg_wm_base_listener = {
wlevent__xdg_wm_base_ping,
};
/* (2) xdg_surface::configure
** " marks the end of a configure sequence ...
** Clients should arrange their surface for the new states, and then
** send an ack_configure request with the serial sent in this
** configure event at some point before committing the new surface. "
*/
static void
wlevent__xdg_surface_configure(void *data, struct xdg_surface *xdg_surface,
uint32_t serial){
xdg_surface_ack_configure(xdg_surface, serial);
wl_surface_commit(ctx.wl_surface);
}
const struct xdg_surface_listener xdg_surface_listener = {
wlevent__xdg_surface_configure,
};
/* (2) xdg_toplevel::configure
** " This configure event asks the client to resize its toplevel surface
** or to change its state. The configured state should not be applied
** immediately. See xdg_surface.configure for details. "
** @see:(xdg_surface::configure)
*/
static void
wlevent__xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
int32_t width, int32_t height,
struct wl_array *states){
if (width > 0 && height > 0){
/* (nodocs-wl_egl) */
wl_egl_window_resize(ctx.wl_egl_window, width, height, 0, 0);
}
}
/* (2) xdg_toplevel::close
** " sent by the compositor when the user wants the surface to be closed. "
*/
static void
wlevent__xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel){
ctx.close_signal = 1;
}
/* (2) xdg_toplevel::configure_bounds
** " sent [...] to communicate the bounds a window geometry size is
** recommended to constrain to "
**~ NOTE: basically "tells you the monitor size".
** @see:xdg_surface.configure
*/
static void
wlevent__xdg_toplevel_configure_bounds(void *data, struct xdg_toplevel *xdg_toplevel,
int32_t width, int32_t height){
}
/* (2) xdg_toplevel::wm_capabilities
** " advertises the capabilities supported by the compositor "
**~ NOTE: basically "tells you the monitor size".
** @see:xdg_surface.configure
*/
static void
wlevent__xdg_toplevel_wm_capabilities(void *data, struct xdg_toplevel *xdg_toplevel,
struct wl_array *capabilities){
}
const struct xdg_toplevel_listener xdg_toplevel_listener = {
wlevent__xdg_toplevel_configure,
wlevent__xdg_toplevel_close,
wlevent__xdg_toplevel_configure_bounds,
wlevent__xdg_toplevel_wm_capabilities,
};
#endif
/* (1) Appendix A: wl_registry::global
** " The event notifies the client that a global object with the given
** name is now available "
@ -214,15 +83,6 @@ wlevent__wl_registry_global(void *data, struct wl_registry *registry,
ctx.wl_compositor = (struct wl_compositor*)
wl_registry_bind(registry, name, &wl_compositor_interface, 1);
}
#if 0
else if (strcmp(interface, "xdg_wm_base") == 0){
ctx.xdg_wm_base = (struct xdg_wm_base*)
wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
/* [1] */
xdg_wm_base_add_listener(ctx.xdg_wm_base, &xdg_wm_base_listener, 0);
}
#endif
}
/* (1) Appendix A: wl_registry::global_remove */
@ -246,7 +106,11 @@ struct libdecor_interface libdecor_interface = {
};
/* (nodocs) */
/* (libdecor.h) libdecor_frame_interface::configure
** " A new configuration was received. An application should respond to
** this by creating a suitable libdecor_state, and apply it using
** libdecor_frame_commit. "
*/
static void
libdecorevent__frame_configure(struct libdecor_frame *frame,
struct libdecor_configuration *config,
@ -255,10 +119,18 @@ libdecorevent__frame_configure(struct libdecor_frame *frame,
int h = ctx.h;
/* (nodocs) */
if (libdecor_configuration_get_content_size(config, frame, &w, &h)){
/* (nodocs) */
struct libdecor_state *state = libdecor_state_new(w, h);
/* (nodocs) */
/* (libdecor.h) libdecor_frame_commit
** " Commit a new window state. This can be called on application
** driven resizes when the window is floating, or in response to
** received configurations, i.e. from e.g. interactive resizes
** or state changes. "
*/
libdecor_frame_commit(frame, state, config);
/* (nodocs) */
libdecor_state_free(state);
}
@ -444,6 +316,13 @@ int main(){
if (ctx.libdecor_frame != 0){
/* (nodocs-libdecor) */
libdecor_frame_set_title(ctx.libdecor_frame, "Example Window");
/* (libdecor.h) " This translates roughly to xdg_toplevel_set_min_size() "
**~ NOTE: I recommend setting this to something greater than 0 on each
** axis, to prevent some artifacts when resize goes 0 or negative.
*/
libdecor_frame_set_min_content_size(ctx.libdecor_frame, 80, 60);
/* (nodocs-libdecor) */
libdecor_frame_map(ctx.libdecor_frame);