decompose wl_backend.c: extract wl_popup.c
This commit is contained in:
parent
c46adc93c5
commit
ac4aa4fe4d
|
|
@ -189,6 +189,7 @@ wmaker_SOURCES += \
|
|||
backend/wayland/wl_pointer_focus.c \
|
||||
backend/wayland/wl_grab.c \
|
||||
backend/wayland/wl_keyboard.c \
|
||||
backend/wayland/wl_popup.c \
|
||||
backend/wayland/wl_xwayland.c \
|
||||
backend/wayland/wl_dock.c \
|
||||
backend/wayland/wl_input_fwd.c
|
||||
|
|
|
|||
|
|
@ -295,6 +295,7 @@ void wl_update_pointer_focus(uint32_t time_msec);
|
|||
void wl_pointer_warp_to(int x, int y);
|
||||
/* wmaker-popup-v1 helper — defined in protocol section below. */
|
||||
void wmaker_popup_apply(struct wl_toplevel_view *view);
|
||||
extern void wmaker_popup_manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id);
|
||||
/* Phase 14: pointer event handler forward declarations. */
|
||||
extern void handle_pointer_motion(struct wl_listener *listener, void *data);
|
||||
/* Phase 24: click-to-focus helper — defined in Phase 13 pointer section. */
|
||||
|
|
@ -788,178 +789,7 @@ 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_parent(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *parent_resource)
|
||||
{
|
||||
(void)client;
|
||||
struct wl_toplevel_view *view = wl_resource_get_user_data(resource);
|
||||
if (!view) return;
|
||||
if (parent_resource) {
|
||||
view->popup_parent = wlr_xdg_toplevel_from_resource(parent_resource);
|
||||
} else {
|
||||
view->popup_parent = NULL;
|
||||
}
|
||||
wwarning("wmaker_popup: set_parent view=%p parent=%p", (void*)view,
|
||||
(void*)view->popup_parent);
|
||||
}
|
||||
|
||||
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);
|
||||
wwarning("wmaker_popup: set_position view=%p (%d,%d)", (void*)view, x, y);
|
||||
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_parent = wmaker_popup_handle_set_parent,
|
||||
.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;
|
||||
}
|
||||
|
||||
void
|
||||
wmaker_popup_apply(struct wl_toplevel_view *view)
|
||||
{
|
||||
if (!view || !view->popup) return;
|
||||
|
||||
/* If a parent was set, translate the requested position into screen
|
||||
* coordinates by adding the parent toplevel's current position. */
|
||||
int target_x = view->popup_x;
|
||||
int target_y = view->popup_y;
|
||||
if (view->popup_parent) {
|
||||
struct wl_toplevel_view *parent_view =
|
||||
wl_find_view_by_xdg_surface(view->popup_parent->base);
|
||||
if (parent_view) {
|
||||
target_x += parent_view->x;
|
||||
target_y += parent_view->y;
|
||||
}
|
||||
}
|
||||
|
||||
int dx = target_x - view->x;
|
||||
int dy = target_y - view->y;
|
||||
wwarning("wmaker_popup_apply: view=%p (%d,%d)->(%d,%d) frame_id=0x%lx scene_node=%p",
|
||||
(void*)view, view->x, view->y, target_x, target_y,
|
||||
(unsigned long)view->frame_id, (void*)view->scene_node);
|
||||
|
||||
view->x = target_x;
|
||||
view->y = target_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);
|
||||
/* Raise above siblings so popups appear over their parent */
|
||||
wlr_scene_node_raise_to_top(&fb->tree->node);
|
||||
wwarning("popup_apply: raised frame tree id=0x%lx to top, parent=%p",
|
||||
(unsigned long)view->id, (void*)fb->tree->node.parent);
|
||||
} else if (fb->scene_buf) {
|
||||
wlr_scene_node_set_position(&fb->scene_buf->node, fb->x, fb->y);
|
||||
wlr_scene_node_raise_to_top(&fb->scene_buf->node);
|
||||
}
|
||||
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);
|
||||
wlr_scene_node_raise_to_top(&view->scene_node->node);
|
||||
wwarning("popup_apply: raised scene_node id=0x%lx to top",
|
||||
(unsigned long)view->id);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* handle_xdg_toplevel_initial_commit -- wlroots 0.19 requires that the
|
||||
|
|
|
|||
|
|
@ -0,0 +1,184 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "wmaker-popup-v1-server-protocol.h"
|
||||
|
||||
#include "wl_types.h"
|
||||
|
||||
/* Forward declarations */
|
||||
struct wl_toplevel_view *wl_find_view_by_xdg_surface(struct wlr_xdg_surface *surf);
|
||||
struct wl_frame_buf *frame_buf_find(WNativeWindow id);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* 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_parent(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *parent_resource)
|
||||
{
|
||||
(void)client;
|
||||
struct wl_toplevel_view *view = wl_resource_get_user_data(resource);
|
||||
if (!view) return;
|
||||
if (parent_resource) {
|
||||
view->popup_parent = wlr_xdg_toplevel_from_resource(parent_resource);
|
||||
} else {
|
||||
view->popup_parent = NULL;
|
||||
}
|
||||
wwarning("wmaker_popup: set_parent view=%p parent=%p", (void*)view,
|
||||
(void*)view->popup_parent);
|
||||
}
|
||||
|
||||
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);
|
||||
wwarning("wmaker_popup: set_position view=%p (%d,%d)", (void*)view, x, y);
|
||||
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_parent = wmaker_popup_handle_set_parent,
|
||||
.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;
|
||||
}
|
||||
|
||||
void
|
||||
wmaker_popup_apply(struct wl_toplevel_view *view)
|
||||
{
|
||||
if (!view || !view->popup) return;
|
||||
|
||||
int target_x = view->popup_x;
|
||||
int target_y = view->popup_y;
|
||||
if (view->popup_parent) {
|
||||
struct wl_toplevel_view *parent_view =
|
||||
wl_find_view_by_xdg_surface(view->popup_parent->base);
|
||||
if (parent_view) {
|
||||
target_x += parent_view->x;
|
||||
target_y += parent_view->y;
|
||||
}
|
||||
}
|
||||
|
||||
int dx = target_x - view->x;
|
||||
int dy = target_y - view->y;
|
||||
wwarning("wmaker_popup_apply: view=%p (%d,%d)->(%d,%d) frame_id=0x%lx scene_node=%p",
|
||||
(void*)view, view->x, view->y, target_x, target_y,
|
||||
(unsigned long)view->frame_id, (void*)view->scene_node);
|
||||
|
||||
view->x = target_x;
|
||||
view->y = target_y;
|
||||
|
||||
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);
|
||||
wlr_scene_node_raise_to_top(&fb->tree->node);
|
||||
wwarning("popup_apply: raised frame tree id=0x%lx to top, parent=%p",
|
||||
(unsigned long)view->id, (void*)fb->tree->node.parent);
|
||||
} else if (fb->scene_buf) {
|
||||
wlr_scene_node_set_position(&fb->scene_buf->node, fb->x, fb->y);
|
||||
wlr_scene_node_raise_to_top(&fb->scene_buf->node);
|
||||
}
|
||||
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);
|
||||
wlr_scene_node_raise_to_top(&view->scene_node->node);
|
||||
wwarning("popup_apply: raised scene_node id=0x%lx to top",
|
||||
(unsigned long)view->id);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
Loading…
Reference in New Issue