scene: add wlr_scene_attach_output_layout
This is a helper to integrate wlr_scene with wlr_output_layout.
This commit is contained in:
parent
7832005a1f
commit
a181a37b12
|
@ -24,6 +24,7 @@
|
|||
#include <wlr/types/wlr_surface.h>
|
||||
|
||||
struct wlr_output;
|
||||
struct wlr_output_layout;
|
||||
|
||||
enum wlr_scene_node_type {
|
||||
WLR_SCENE_NODE_ROOT,
|
||||
|
@ -203,4 +204,13 @@ void wlr_scene_output_set_position(struct wlr_scene_output *scene_output,
|
|||
*/
|
||||
bool wlr_scene_output_commit(struct wlr_scene_output *scene_output);
|
||||
|
||||
/**
|
||||
* Attach an output layout to a scene.
|
||||
*
|
||||
* Outputs in the output layout are automatically added to the scene. Any
|
||||
* change to the output layout is mirrored to the scene-graph outputs.
|
||||
*/
|
||||
bool wlr_scene_attach_output_layout(struct wlr_scene *scene,
|
||||
struct wlr_output_layout *output_layout);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,7 @@ wlr_files += files(
|
|||
'data_device/wlr_data_source.c',
|
||||
'data_device/wlr_drag.c',
|
||||
'scene/wlr_scene.c',
|
||||
'scene/output_layout.c',
|
||||
'seat/wlr_seat_keyboard.c',
|
||||
'seat/wlr_seat_pointer.c',
|
||||
'seat/wlr_seat_touch.c',
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
#include <stdlib.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
|
||||
struct wlr_scene_output_layout {
|
||||
struct wlr_output_layout *layout;
|
||||
struct wlr_scene *scene;
|
||||
|
||||
struct wl_listener layout_add;
|
||||
struct wl_listener layout_change;
|
||||
struct wl_listener layout_destroy;
|
||||
struct wl_listener scene_destroy;
|
||||
};
|
||||
|
||||
static void scene_output_layout_destroy(struct wlr_scene_output_layout *sol) {
|
||||
wl_list_remove(&sol->layout_destroy.link);
|
||||
wl_list_remove(&sol->layout_add.link);
|
||||
wl_list_remove(&sol->layout_change.link);
|
||||
wl_list_remove(&sol->scene_destroy.link);
|
||||
free(sol);
|
||||
}
|
||||
|
||||
static void scene_output_layout_handle_layout_destroy(
|
||||
struct wl_listener *listener, void *data) {
|
||||
struct wlr_scene_output_layout *sol =
|
||||
wl_container_of(listener, sol, layout_destroy);
|
||||
|
||||
// Remove all outputs managed by the output layout
|
||||
struct wlr_scene_output *scene_output, *tmp;
|
||||
wl_list_for_each_safe(scene_output, tmp, &sol->scene->outputs, link) {
|
||||
struct wlr_output_layout_output *lo =
|
||||
wlr_output_layout_get(sol->layout, scene_output->output);
|
||||
if (lo != NULL) {
|
||||
wlr_scene_output_destroy(scene_output);
|
||||
}
|
||||
}
|
||||
|
||||
scene_output_layout_destroy(sol);
|
||||
}
|
||||
|
||||
static void scene_output_layout_handle_layout_change(
|
||||
struct wl_listener *listener, void *data) {
|
||||
struct wlr_scene_output_layout *sol =
|
||||
wl_container_of(listener, sol, layout_change);
|
||||
|
||||
struct wlr_scene_output *scene_output, *tmp;
|
||||
wl_list_for_each_safe(scene_output, tmp, &sol->scene->outputs, link) {
|
||||
struct wlr_output_layout_output *lo =
|
||||
wlr_output_layout_get(sol->layout, scene_output->output);
|
||||
if (lo == NULL) {
|
||||
// Output has been removed from the layout
|
||||
wlr_scene_output_destroy(scene_output);
|
||||
continue;
|
||||
}
|
||||
|
||||
wlr_scene_output_set_position(scene_output, lo->x, lo->y);
|
||||
}
|
||||
}
|
||||
|
||||
static void scene_output_layout_handle_layout_add(
|
||||
struct wl_listener *listener, void *data) {
|
||||
struct wlr_scene_output_layout *sol =
|
||||
wl_container_of(listener, sol, layout_add);
|
||||
struct wlr_output_layout_output *lo = data;
|
||||
|
||||
struct wlr_scene_output *scene_output =
|
||||
wlr_scene_output_create(sol->scene, lo->output);
|
||||
if (scene_output == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_scene_output_set_position(scene_output, lo->x, lo->y);
|
||||
}
|
||||
|
||||
static void scene_output_layout_handle_scene_destroy(
|
||||
struct wl_listener *listener, void *data) {
|
||||
struct wlr_scene_output_layout *sol =
|
||||
wl_container_of(listener, sol, scene_destroy);
|
||||
scene_output_layout_destroy(sol);
|
||||
}
|
||||
|
||||
bool wlr_scene_attach_output_layout(struct wlr_scene *scene,
|
||||
struct wlr_output_layout *output_layout) {
|
||||
struct wlr_scene_output_layout *sol = calloc(1, sizeof(*sol));
|
||||
if (sol == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sol->scene = scene;
|
||||
sol->layout = output_layout;
|
||||
|
||||
sol->layout_destroy.notify = scene_output_layout_handle_layout_destroy;
|
||||
wl_signal_add(&output_layout->events.destroy, &sol->layout_destroy);
|
||||
|
||||
sol->layout_change.notify = scene_output_layout_handle_layout_change;
|
||||
wl_signal_add(&output_layout->events.change, &sol->layout_change);
|
||||
|
||||
sol->layout_add.notify = scene_output_layout_handle_layout_add;
|
||||
wl_signal_add(&output_layout->events.add, &sol->layout_add);
|
||||
|
||||
sol->scene_destroy.notify = scene_output_layout_handle_scene_destroy;
|
||||
wl_signal_add(&output_layout->events.destroy, &sol->scene_destroy);
|
||||
|
||||
return true;
|
||||
}
|
Loading…
Reference in New Issue