Implement wmaker-popup-v1 Wayland protocol for client-driven popup positioning
Standard xdg_shell does not allow Wayland clients to position toplevels — the compositor decides placement. WINGs UI patterns require client-driven positioning (e.g., a dropdown popup must appear directly below its trigger button; menu editor items must be placed by the client at specific screen coordinates). This protocol lets the client wrap an xdg_toplevel with a wmaker_popup object and call set_position(x, y) before the surface is mapped. The compositor honours the requested position when the surface becomes visible and on subsequent set_position calls. Files: - protocols/wmaker-popup-v1.xml: protocol definition - src/Makefile.am, src/Makefile: server-protocol.h + protocol.c generation - WINGs/Makefile.am, WINGs/Makefile: client-protocol.h + protocol.c generation - src/backend/wayland/wl_backend.c: wmaker_popup_manager global, get_popup handler that wraps an xdg_toplevel; set_position handler that updates view->popup_x/y and calls wmaker_popup_apply to move the frame_buf scene tree. Apply runs at toplevel_map time too for pre-map positions. - WINGs/wclient_wl.c: bind manager in registry, wrap popup toplevels with wmaker_popup, expose W_WLClientPopupSetPosition. - WINGs/wview_wl.c: wl_move calls W_WLClientPopupSetPosition for popup toplevels so WMMoveWidget propagates to the compositor. - WINGs/wevent_wl.c: wl_move_window also routes to popup positioning.
This commit is contained in:
parent
fd73e94a58
commit
60348da411
|
|
@ -104,9 +104,13 @@ endif
|
|||
if USE_WAYLAND_CLIENT
|
||||
nodist_libWINGs_la_SOURCES = \
|
||||
xdg-shell-protocol.c \
|
||||
xdg-shell-client-protocol.h
|
||||
BUILT_SOURCES = xdg-shell-client-protocol.h xdg-shell-protocol.c
|
||||
CLEANFILES = xdg-shell-client-protocol.h xdg-shell-protocol.c
|
||||
xdg-shell-client-protocol.h \
|
||||
wmaker-popup-v1-protocol.c \
|
||||
wmaker-popup-v1-client-protocol.h
|
||||
BUILT_SOURCES = xdg-shell-client-protocol.h xdg-shell-protocol.c \
|
||||
wmaker-popup-v1-client-protocol.h wmaker-popup-v1-protocol.c
|
||||
CLEANFILES = xdg-shell-client-protocol.h xdg-shell-protocol.c \
|
||||
wmaker-popup-v1-client-protocol.h wmaker-popup-v1-protocol.c
|
||||
|
||||
xdg-shell-client-protocol.h:
|
||||
$(WAYLAND_SCANNER) client-header \
|
||||
|
|
@ -115,6 +119,13 @@ xdg-shell-client-protocol.h:
|
|||
xdg-shell-protocol.c: xdg-shell-client-protocol.h
|
||||
$(WAYLAND_SCANNER) private-code \
|
||||
$(WAYLAND_PROTOCOLS_DIR)/stable/xdg-shell/xdg-shell.xml $@
|
||||
|
||||
wmaker-popup-v1-client-protocol.h: $(top_srcdir)/protocols/wmaker-popup-v1.xml
|
||||
$(WAYLAND_SCANNER) client-header $< $@
|
||||
|
||||
wmaker-popup-v1-protocol.c: $(top_srcdir)/protocols/wmaker-popup-v1.xml \
|
||||
wmaker-popup-v1-client-protocol.h
|
||||
$(WAYLAND_SCANNER) private-code $< $@
|
||||
endif
|
||||
|
||||
libWUtil_la_SOURCES = \
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include <wayland-client.h>
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
#include "wmaker-popup-v1-client-protocol.h"
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
|
|
@ -63,6 +64,8 @@ typedef struct WLClientCtx {
|
|||
struct wl_shm *shm;
|
||||
struct wl_seat *seat;
|
||||
struct xdg_wm_base *wm_base;
|
||||
/* wmaker-popup-v1: client-driven popup positioning */
|
||||
struct wmaker_popup_manager_v1 *wmaker_popup_mgr;
|
||||
|
||||
struct wl_pointer *pointer;
|
||||
struct wl_keyboard *keyboard;
|
||||
|
|
@ -221,6 +224,8 @@ typedef struct WLClientToplevel {
|
|||
struct wl_surface *surface;
|
||||
struct xdg_surface *xdg_surface;
|
||||
struct xdg_toplevel *xdg_toplevel;
|
||||
/* wmaker-popup-v1 wrapper for client-driven positioning (NULL if not popup) */
|
||||
struct wmaker_popup_v1 *wmaker_popup;
|
||||
|
||||
WLClientShmBuffer *buf; /* current backing */
|
||||
|
||||
|
|
@ -412,6 +417,7 @@ wl_client_view_destroy_backing(unsigned long id)
|
|||
{
|
||||
WLClientToplevel *top = wlc_top_find((WNativeWindow)id);
|
||||
if (!top) return;
|
||||
if (top->wmaker_popup) wmaker_popup_v1_destroy(top->wmaker_popup);
|
||||
if (top->xdg_toplevel) xdg_toplevel_destroy(top->xdg_toplevel);
|
||||
if (top->xdg_surface) xdg_surface_destroy(top->xdg_surface);
|
||||
if (top->surface) wl_surface_destroy(top->surface);
|
||||
|
|
@ -453,6 +459,16 @@ wl_client_toplevel_realize(struct W_View *view, int width, int height)
|
|||
if (view->flags.popup) {
|
||||
xdg_toplevel_set_app_id(top->xdg_toplevel, "wings-popup");
|
||||
xdg_toplevel_set_title(top->xdg_toplevel, "");
|
||||
/* Wrap with wmaker-popup-v1 so we can drive position. */
|
||||
if (ctx->wmaker_popup_mgr) {
|
||||
top->wmaker_popup = wmaker_popup_manager_v1_get_popup(
|
||||
ctx->wmaker_popup_mgr, top->xdg_toplevel);
|
||||
/* Apply any position recorded in view->pos before realize. */
|
||||
if (top->wmaker_popup && (view->pos.x || view->pos.y)) {
|
||||
wmaker_popup_v1_set_position(top->wmaker_popup,
|
||||
view->pos.x, view->pos.y);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
xdg_toplevel_set_app_id(top->xdg_toplevel, "WINGs");
|
||||
xdg_toplevel_set_title(top->xdg_toplevel, "WINGs Application");
|
||||
|
|
@ -515,6 +531,14 @@ W_WLClientSetMinMaxSize(W_View *view)
|
|||
wl_surface_commit(top->surface);
|
||||
}
|
||||
|
||||
void
|
||||
W_WLClientPopupSetPosition(WNativeWindow window, int x, int y)
|
||||
{
|
||||
WLClientToplevel *top = wlc_top_find(window);
|
||||
if (!top || !top->wmaker_popup) return;
|
||||
wmaker_popup_v1_set_position(top->wmaker_popup, x, y);
|
||||
}
|
||||
|
||||
Bool
|
||||
W_WLClientBeginMove(WNativeWindow window)
|
||||
{
|
||||
|
|
@ -1036,6 +1060,9 @@ registry_handle_global(void *data, struct wl_registry *registry,
|
|||
ctx->wm_base = wl_registry_bind(registry, name,
|
||||
&xdg_wm_base_interface, v);
|
||||
xdg_wm_base_add_listener(ctx->wm_base, &wm_base_listener, ctx);
|
||||
} else if (strcmp(interface, wmaker_popup_manager_v1_interface.name) == 0) {
|
||||
ctx->wmaker_popup_mgr = wl_registry_bind(registry, name,
|
||||
&wmaker_popup_manager_v1_interface, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -216,8 +216,13 @@ static Bool wl_get_window_geometry(void *ectx, WNativeWindow w,
|
|||
if (width) *width = 0; if (height) *height = 0;
|
||||
return False; }
|
||||
|
||||
extern void W_WLClientPopupSetPosition(WNativeWindow w, int x, int y);
|
||||
|
||||
static void wl_move_window(void *ectx, WNativeWindow w, int x, int y)
|
||||
{ (void)ectx; (void)w; (void)x; (void)y; }
|
||||
{
|
||||
(void)ectx;
|
||||
W_WLClientPopupSetPosition(w, x, y);
|
||||
}
|
||||
|
||||
/* Implemented in wclient_wl.c — calls xdg_toplevel_move on the client
|
||||
* connection so the compositor handles the drag. */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
/* Generated by wayland-scanner 1.24.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2026 Window Maker Team
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||
#endif
|
||||
|
||||
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||
#else
|
||||
#define WL_PRIVATE
|
||||
#endif
|
||||
|
||||
extern const struct wl_interface wmaker_popup_v1_interface;
|
||||
extern const struct wl_interface xdg_toplevel_interface;
|
||||
|
||||
static const struct wl_interface *wmaker_popup_v1_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
&wmaker_popup_v1_interface,
|
||||
&xdg_toplevel_interface,
|
||||
};
|
||||
|
||||
static const struct wl_message wmaker_popup_manager_v1_requests[] = {
|
||||
{ "destroy", "", wmaker_popup_v1_types + 0 },
|
||||
{ "get_popup", "no", wmaker_popup_v1_types + 2 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface wmaker_popup_manager_v1_interface = {
|
||||
"wmaker_popup_manager_v1", 1,
|
||||
2, wmaker_popup_manager_v1_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message wmaker_popup_v1_requests[] = {
|
||||
{ "destroy", "", wmaker_popup_v1_types + 0 },
|
||||
{ "set_position", "ii", wmaker_popup_v1_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface wmaker_popup_v1_interface = {
|
||||
"wmaker_popup_v1", 1,
|
||||
2, wmaker_popup_v1_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
|
|
@ -316,6 +316,14 @@ static void wl_move(void *vctx, W_View *view, int x, int y)
|
|||
(void)vctx;
|
||||
view->pos.x = x;
|
||||
view->pos.y = y;
|
||||
/* For popup-style toplevels, drive position via wmaker-popup-v1.
|
||||
* The client function is a no-op if the toplevel hasn't been
|
||||
* realized yet — pos.x/y is captured into view->pos for the
|
||||
* realize-time call. */
|
||||
if (view->flags.topLevel && view->flags.popup && view->flags.realized) {
|
||||
extern void W_WLClientPopupSetPosition(WNativeWindow w, int x, int y);
|
||||
W_WLClientPopupSetPosition((WNativeWindow)view->window, x, y);
|
||||
}
|
||||
if (view->parent && view->flags.mapped)
|
||||
wl_redisplay(vctx, view->parent);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,27 @@
|
|||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
|
||||
BUILT_SOURCES = wconfig.h
|
||||
BUILT_SOURCES = wconfig.h \
|
||||
wmaker-popup-v1-server-protocol.h \
|
||||
wmaker-popup-v1-protocol.c
|
||||
|
||||
bin_PROGRAMS = wmaker
|
||||
|
||||
EXTRA_DIST =
|
||||
|
||||
nodist_wmaker_SOURCES = \
|
||||
wmaker-popup-v1-protocol.c \
|
||||
wmaker-popup-v1-server-protocol.h
|
||||
|
||||
CLEANFILES = wmaker-popup-v1-server-protocol.h \
|
||||
wmaker-popup-v1-protocol.c
|
||||
|
||||
wmaker-popup-v1-server-protocol.h: $(top_srcdir)/protocols/wmaker-popup-v1.xml
|
||||
$(WAYLAND_SCANNER) server-header $< $@
|
||||
|
||||
wmaker-popup-v1-protocol.c: $(top_srcdir)/protocols/wmaker-popup-v1.xml \
|
||||
wmaker-popup-v1-server-protocol.h
|
||||
$(WAYLAND_SCANNER) private-code $< $@
|
||||
|
||||
wmaker_SOURCES = \
|
||||
GNUstep.h \
|
||||
WindowMaker.h \
|
||||
|
|
@ -148,10 +164,10 @@ if USE_NESTED_FUNC
|
|||
wmaker_SOURCES += misc.c \
|
||||
xmodifier.c
|
||||
else
|
||||
nodist_wmaker_SOURCES = misc.hack_nf.c \
|
||||
nodist_wmaker_SOURCES += misc.hack_nf.c \
|
||||
xmodifier.hack_nf.c
|
||||
|
||||
CLEANFILES = $(nodist_wmaker_SOURCES)
|
||||
CLEANFILES += misc.hack_nf.c xmodifier.hack_nf.c
|
||||
|
||||
misc.hack_nf.c: misc.c $(top_srcdir)/script/nested-func-to-macro.sh
|
||||
$(AM_V_GEN)$(top_srcdir)/script/nested-func-to-macro.sh \
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@
|
|||
#include <wlr/types/wlr_seat.h>
|
||||
#include <wlr/types/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include "wmaker-popup-v1-server-protocol.h"
|
||||
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
||||
#include <wlr/xwayland.h> /* Phase 17: XWayland support */
|
||||
#include <X11/Xproto.h> /* X_SetInputFocus and other request codes */
|
||||
|
|
@ -273,6 +274,9 @@ struct wl_toplevel_view {
|
|||
WNativeWindow frame_id; /* frame_buf that owns this view (0 = none) */
|
||||
int frame_rel_x, frame_rel_y; /* offset within frame */
|
||||
int x, y; /* Phase 55: WM-assigned position */
|
||||
/* wmaker-popup-v1: client-driven popup position (only valid if popup != NULL) */
|
||||
struct wl_resource *popup; /* wmaker_popup_v1 resource or NULL */
|
||||
int popup_x, popup_y;
|
||||
long *wm_state; /* Phase 56: saved WM state or NULL */
|
||||
int wm_state_n; /* Phase 56: element count */
|
||||
char **wm_command; /* Phase 57: WM_COMMAND argv or NULL */
|
||||
|
|
@ -362,6 +366,8 @@ struct wl_compositor_state {
|
|||
struct wlr_seat *seat;
|
||||
struct wlr_data_device_manager *data_device_mgr;
|
||||
struct wlr_xdg_shell *xdg_shell;
|
||||
/* wmaker-popup-v1 protocol global — client-driven popup positioning */
|
||||
struct wl_global *wmaker_popup_manager;
|
||||
/* Phase 64: XDG decoration manager — tell clients to use CSD */
|
||||
struct wlr_xdg_decoration_manager_v1 *decoration_manager;
|
||||
struct wl_listener decoration_new_listener;
|
||||
|
|
@ -681,6 +687,8 @@ static int wl_client_get_pid(WNativeWindow win);
|
|||
/* Phase 13: forward declarations — defined in pointer section below. */
|
||||
static void wl_update_pointer_focus(uint32_t time_msec);
|
||||
static void wl_pointer_warp_to(int x, int y);
|
||||
/* wmaker-popup-v1 helper — defined in protocol section below. */
|
||||
static void wmaker_popup_apply(struct wl_toplevel_view *view);
|
||||
/* Phase 14: pointer event handler forward declarations. */
|
||||
static void handle_pointer_motion(struct wl_listener *listener, void *data);
|
||||
/* Phase 24: click-to-focus helper — defined in Phase 13 pointer section. */
|
||||
|
|
@ -1165,6 +1173,10 @@ handle_toplevel_map(struct wl_listener *listener, void *data)
|
|||
/* Rebuild frame without decorations */
|
||||
extern void wWindowConfigureBorders(WWindow *wwin);
|
||||
wWindowConfigureBorders(wwin);
|
||||
/* If the client requested a position via wmaker-popup-v1,
|
||||
* apply it now that the frame is set up. */
|
||||
if (view->popup)
|
||||
wmaker_popup_apply(view);
|
||||
}
|
||||
int pid = wl_client_get_pid(view->id);
|
||||
/* Phase 62: focus delivered by wManageWindow via wSetFocusTo
|
||||
|
|
@ -1366,6 +1378,136 @@ handle_new_toplevel_decoration(struct wl_listener *listener, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* wmaker-popup-v1 protocol — client-driven popup positioning */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
wmaker_popup_handle_destroy(struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
(void)client;
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
||||
static void
|
||||
wmaker_popup_handle_set_position(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
int32_t x, int32_t y)
|
||||
{
|
||||
(void)client;
|
||||
struct wl_toplevel_view *view = wl_resource_get_user_data(resource);
|
||||
if (!view) return;
|
||||
view->popup_x = (int)x;
|
||||
view->popup_y = (int)y;
|
||||
wmaker_popup_apply(view);
|
||||
}
|
||||
|
||||
static const struct wmaker_popup_v1_interface wmaker_popup_impl = {
|
||||
.destroy = wmaker_popup_handle_destroy,
|
||||
.set_position = wmaker_popup_handle_set_position,
|
||||
};
|
||||
|
||||
static void
|
||||
wmaker_popup_resource_destroy(struct wl_resource *resource)
|
||||
{
|
||||
struct wl_toplevel_view *view = wl_resource_get_user_data(resource);
|
||||
if (view && view->popup == resource)
|
||||
view->popup = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
wmaker_popup_apply(struct wl_toplevel_view *view)
|
||||
{
|
||||
if (!view || !view->popup) return;
|
||||
|
||||
/* Update the canonical view position so subsequent compositor logic
|
||||
* (frame moves, scene-node positioning) sees the new placement. */
|
||||
int dx = view->popup_x - view->x;
|
||||
int dy = view->popup_y - view->y;
|
||||
view->x = view->popup_x;
|
||||
view->y = view->popup_y;
|
||||
|
||||
/* If a frame_buf wraps this view, move it via the WM's window-move
|
||||
* path so the frame and its tree node update consistently. */
|
||||
if (view->frame_id) {
|
||||
struct wl_frame_buf *fb = frame_buf_find(view->frame_id);
|
||||
if (fb) {
|
||||
fb->x += dx;
|
||||
fb->y += dy;
|
||||
if (fb->tree)
|
||||
wlr_scene_node_set_position(&fb->tree->node, fb->x, fb->y);
|
||||
else if (fb->scene_buf)
|
||||
wlr_scene_node_set_position(&fb->scene_buf->node, fb->x, fb->y);
|
||||
view->frame_rel_x = 0;
|
||||
view->frame_rel_y = 0;
|
||||
}
|
||||
} else if (view->scene_node) {
|
||||
wlr_scene_node_set_position(&view->scene_node->node,
|
||||
view->x, view->y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wmaker_popup_manager_handle_destroy(struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
(void)client;
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
||||
static void
|
||||
wmaker_popup_manager_handle_get_popup(struct wl_client *client,
|
||||
struct wl_resource *manager_resource,
|
||||
uint32_t id,
|
||||
struct wl_resource *toplevel_resource)
|
||||
{
|
||||
(void)manager_resource;
|
||||
struct wlr_xdg_toplevel *xdg_top =
|
||||
wlr_xdg_toplevel_from_resource(toplevel_resource);
|
||||
if (!xdg_top) {
|
||||
wl_resource_post_error(manager_resource, 0,
|
||||
"wmaker_popup: invalid xdg_toplevel resource");
|
||||
return;
|
||||
}
|
||||
|
||||
struct wl_toplevel_view *view =
|
||||
wl_find_view_by_xdg_surface(xdg_top->base);
|
||||
|
||||
struct wl_resource *resource = wl_resource_create(client,
|
||||
&wmaker_popup_v1_interface, 1, id);
|
||||
if (!resource) {
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
wl_resource_set_implementation(resource, &wmaker_popup_impl,
|
||||
view, wmaker_popup_resource_destroy);
|
||||
|
||||
if (view)
|
||||
view->popup = resource;
|
||||
}
|
||||
|
||||
static const struct wmaker_popup_manager_v1_interface wmaker_popup_manager_impl = {
|
||||
.destroy = wmaker_popup_manager_handle_destroy,
|
||||
.get_popup = wmaker_popup_manager_handle_get_popup,
|
||||
};
|
||||
|
||||
static void
|
||||
wmaker_popup_manager_bind(struct wl_client *client, void *data,
|
||||
uint32_t version, uint32_t id)
|
||||
{
|
||||
(void)data;
|
||||
struct wl_resource *resource = wl_resource_create(client,
|
||||
&wmaker_popup_manager_v1_interface,
|
||||
version > 1 ? 1 : (int)version, id);
|
||||
if (!resource) {
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
wl_resource_set_implementation(resource, &wmaker_popup_manager_impl,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Phase 17: XWayland surface lifecycle */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
@ -2788,6 +2930,13 @@ wl_display_open(const char *name)
|
|||
|
||||
wl_state.xdg_shell = wlr_xdg_shell_create(wl_state.display, 3);
|
||||
|
||||
/* Advertise wmaker-popup-v1 — clients use it to drive popup positioning. */
|
||||
wl_state.wmaker_popup_manager = wl_global_create(wl_state.display,
|
||||
&wmaker_popup_manager_v1_interface, 1, NULL,
|
||||
wmaker_popup_manager_bind);
|
||||
if (wl_state.wmaker_popup_manager)
|
||||
wwarning("wl_backend: wmaker-popup-v1 manager created");
|
||||
|
||||
/* Phase 64: advertise zxdg_decoration_manager_v1 so clients that
|
||||
* support server-side decorations can negotiate; we respond with
|
||||
* CLIENT_SIDE since the Wayland path has no X11 frame rendering. */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
/* Generated by wayland-scanner 1.24.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2026 Window Maker Team
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||
#endif
|
||||
|
||||
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||
#else
|
||||
#define WL_PRIVATE
|
||||
#endif
|
||||
|
||||
extern const struct wl_interface wmaker_popup_v1_interface;
|
||||
extern const struct wl_interface xdg_toplevel_interface;
|
||||
|
||||
static const struct wl_interface *wmaker_popup_v1_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
&wmaker_popup_v1_interface,
|
||||
&xdg_toplevel_interface,
|
||||
};
|
||||
|
||||
static const struct wl_message wmaker_popup_manager_v1_requests[] = {
|
||||
{ "destroy", "", wmaker_popup_v1_types + 0 },
|
||||
{ "get_popup", "no", wmaker_popup_v1_types + 2 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface wmaker_popup_manager_v1_interface = {
|
||||
"wmaker_popup_manager_v1", 1,
|
||||
2, wmaker_popup_manager_v1_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message wmaker_popup_v1_requests[] = {
|
||||
{ "destroy", "", wmaker_popup_v1_types + 0 },
|
||||
{ "set_position", "ii", wmaker_popup_v1_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface wmaker_popup_v1_interface = {
|
||||
"wmaker_popup_v1", 1,
|
||||
2, wmaker_popup_v1_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue