Skip to content

Commit

Permalink
Break up view creation and placement, add positioning functions
Browse files Browse the repository at this point in the history
Split view initialization into two steps; we can't initialize the
scene tree until we know where the node is going to be initially
placed, but the backend code doesn't know how to do that.

Also add additional functions that allow a view's size and location to
be set.
  • Loading branch information
sdilts committed Oct 28, 2023
1 parent 54394d9 commit a10eef4
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 16 deletions.
21 changes: 21 additions & 0 deletions heart/include/hrt/hrt_view.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
#include <stdint.h>
#include <wayland-server-core.h>
#include "hrt/hrt_server.h"

struct hrt_view {
struct wlr_xdg_surface *xdg_surface;
struct wlr_xdg_toplevel *xdg_toplevel;
/*
Contains the tree with the xdg surface tree
plus decorations and that sort of thing.
*/
struct wlr_scene_tree *scene_tree;
struct wl_listener map;
struct wl_listener unmap;
struct wl_listener destroy;
};

/**
* Fully initialize the view and place it in the given scene tree.
**/
void hrt_view_init(struct hrt_view *view, struct wlr_scene_tree *tree);

/**
* Request that this view be the given size. Returns the associated configure serial.
**/
uint32_t hrt_view_set_size(struct hrt_view *view, int width, int height);

/**
* Sets the view to the given coordinates relative to its parent.
**/
void hrt_view_set_relative(struct hrt_view *view, int x, int y);
9 changes: 5 additions & 4 deletions heart/src/meson.build
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
hrt_source_files += files(
'server.c',
'output.c',
'cursor.c',
'input.c',
'seat.c',
'keyboard.c',
'cursor.c',
'output.c',
'seat.c',
'server.c',
'view.c',
'xdg_shell.c',
)
27 changes: 15 additions & 12 deletions heart/src/xdg_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,13 @@ static void handle_xdg_toplevel_destroy(struct wl_listener *listener,
free(view);
}

struct hrt_view *initialize_view(struct wlr_xdg_surface *xdg_surface, struct wlr_scene_tree *tree) {
static struct hrt_view *create_view_from_xdg_surface(struct wlr_xdg_surface *xdg_surface) {
// This method can only deal with toplevel xdg_surfaces:
assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
struct hrt_view *view = calloc(1, sizeof(struct hrt_view));
view->xdg_toplevel = xdg_surface->toplevel;
view->xdg_surface = xdg_surface;

// Add the view to the scene tree (we should probab
view->scene_tree = wlr_scene_xdg_surface_create(tree, view->xdg_toplevel->base);
view->scene_tree->node.data = view;
xdg_surface->data = view->scene_tree;

// Listen to events:
view->map.notify = handle_xdg_toplevel_map;
wl_signal_add(&xdg_surface->events.map, &view->map);
view->unmap.notify = handle_xdg_toplevel_unmap;
Expand All @@ -54,23 +49,31 @@ struct hrt_view *initialize_view(struct wlr_xdg_surface *xdg_surface, struct wlr
return view;
}


void handle_new_xdg_surface(struct wl_listener *listener, void *data) {
wlr_log(WLR_DEBUG, "New XDG Surface recieved");
struct hrt_server *server = wl_container_of(listener, server, new_xdg_surface);
struct wlr_xdg_surface *xdg_surface = data;

if(xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
// We the front end doesn't need to know about popups; wlroots handles it for us.
// The front end doesn't need to know about popups; wlroots handles it for us.
// we do need to set some internal data so that they can be rendered though.
struct wlr_xdg_surface *parent = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent);
struct wlr_scene_tree *parent_tree = parent->data;
xdg_surface->data = wlr_scene_xdg_surface_create(
parent_tree, xdg_surface);
// The parent view might not have been initizlized properly. In that case, it
// isn't being displayed, so we just ignore it:
if (parent_tree) {
xdg_surface->data = wlr_scene_xdg_surface_create(parent_tree, xdg_surface);
} else {
wlr_log(WLR_ERROR, "Encountered XDG Popup without properly configured parent");
}
return;
}

// Initialization occurs in two steps so the consumer can place the view where it needs to go;
// in order to create a scene tree node, it must have a parent.
// We don't have it until the callback.
struct hrt_view *view = create_view_from_xdg_surface(xdg_surface);
// At some point, we will want the front end to call this, as it should decide what node
// of the scene graph the view gets added to:
initialize_view(xdg_surface, &server->scene->tree);
hrt_view_init(view, &server->scene->tree);
}
18 changes: 18 additions & 0 deletions lisp/bindings/hrt-bindings.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,26 @@ See themes section of man xcursor(3) to find where to find valid cursor names."
;; next section imported from file build/include/hrt/hrt_view.h

(cffi:defcstruct hrt-view
(xdg-surface :pointer #| (:struct wlr-xdg-surface) |# )
(xdg-toplevel :pointer #| (:struct wlr-xdg-toplevel) |# )
(scene-tree :pointer #| (:struct wlr-scene-tree) |# )
(map (:struct wl-listener))
(unmap (:struct wl-listener))
(destroy (:struct wl-listener)))

(cffi:defcfun ("hrt_view_init" hrt-view-init) :void
"Fully initialize the view and place it in the given scene tree."
(view (:pointer (:struct hrt-view)))
(tree :pointer #| (:struct wlr-scene-tree) |# ))

(cffi:defcfun ("hrt_view_set_size" hrt-view-set-size) :uint32
"Request that this view be the given size. Returns the associated configure serial."
(view (:pointer (:struct hrt-view)))
(width :int)
(height :int))

(cffi:defcfun ("hrt_view_set_relative" hrt-view-set-relative) :void
"Sets the view to the given coordinates relative to its parent."
(view (:pointer (:struct hrt-view)))
(x :int)
(y :int))

0 comments on commit a10eef4

Please sign in to comment.