diff --git a/wayland_libdecor_egl.c b/wayland_libdecor_egl.c index 9b7c22d..1bde13f 100755 --- a/wayland_libdecor_egl.c +++ b/wayland_libdecor_egl.c @@ -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 #include @@ -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);