Get window up and running

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
2025-09-30 15:26:30 +03:00
parent d193ef0295
commit ed429d6a30
6 changed files with 300 additions and 111 deletions

View File

@@ -3,6 +3,9 @@
#include "common.h"
#include "vec.h"
#include <wlr/render/pass.h>
#include <wlr/render/color.h>
#include <assert.h>
#include <math.h>
#include <stdio.h>
@@ -15,6 +18,10 @@
#include <xkbcommon/xkbcommon-keysyms.h>
#include <xkbcommon/xkbcommon.h>
static void handle_new_output(struct wl_listener *listener, void *data);
static void handle_output_frame(struct wl_listener *listener, void *data);
static void handle_output_destroy(struct wl_listener *listener, void *data);
static inline SphericalCoord get_forward_spherical_with_nearest(
Vector3 fwd, float r)
{
@@ -1481,12 +1488,151 @@ static void setup_xwayland(LunarWM *this)
wl_signal_add(&this->wayland.xwayland->events.new_surface,
&this->wayland.xwayland_new_surface);
}
static void destroy_output(LunarWM_Output *output) {
if (!output) {
return;
}
if (output->frame.link.prev || output->frame.link.next) {
wl_list_remove(&output->frame.link);
}
if (output->destroy.link.prev || output->destroy.link.next) {
wl_list_remove(&output->destroy.link);
}
free(output);
}
static void handle_output_destroy(struct wl_listener *listener, void *data) {
(void)data;
LunarWM_Output *output = wl_container_of(listener, output, destroy);
LunarWM *wm = output->wm;
if (wm && wm->wayland.v_outputs) {
for (size_t i = 0; i < vector_size(wm->wayland.v_outputs); ++i) {
if (wm->wayland.v_outputs[i] == output) {
vector_remove(wm->wayland.v_outputs, i);
break;
}
}
}
destroy_output(output);
}
static void handle_output_frame(struct wl_listener *listener, void *data) {
(void)data;
LunarWM_Output *output = wl_container_of(listener, output, frame);
LunarWM *wm = output->wm;
struct wlr_output *wlr_output = output->wlr_output;
if (wm->xr.available) {
wlr_output_schedule_frame(wlr_output);
return;
}
struct wlr_output_state state;
wlr_output_state_init(&state);
struct wlr_render_pass *pass
= wlr_output_begin_render_pass(wlr_output, &state, NULL);
if (pass == NULL) {
wlr_output_state_finish(&state);
wlr_output_schedule_frame(wlr_output);
wlr_log(WLR_ERROR, "Failed to begin render pass for output %s",
wlr_output->name);
return;
}
struct wlr_box box = {
.x = 0,
.y = 0,
.width = wlr_output->width,
.height = wlr_output->height,
};
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
.box = box,
.color = {
.r = 1.0f,
.g = 0.0f,
.b = 0.0f,
.a = 1.0f,
},
});
if (!wlr_render_pass_submit(pass)) {
wlr_output_state_finish(&state);
wlr_output_schedule_frame(wlr_output);
wlr_log(WLR_ERROR, "Failed to submit render pass for output %s",
wlr_output->name);
return;
}
if (!wlr_output_commit_state(wlr_output, &state)) {
wlr_log(WLR_ERROR, "Failed to commit state for output %s",
wlr_output->name);
wlr_output_state_finish(&state);
wlr_output_schedule_frame(wlr_output);
return;
}
wlr_output_state_finish(&state);
}
static void handle_new_output(struct wl_listener *listener, void *data) {
struct wlr_output *wlr_output = data;
LunarWM *wm = wl_container_of(listener, wm, wayland.new_output_listener);
if (!wlr_output_init_render(
wlr_output, wm->wayland.allocator, wm->wayland.renderer)) {
wlr_log(WLR_ERROR, "Failed to init render for output %s",
wlr_output->name);
return;
}
struct wlr_output_state state;
wlr_output_state_init(&state);
wlr_output_state_set_enabled(&state, true);
struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
if (mode != NULL) {
wlr_output_state_set_mode(&state, mode);
}
bool committed = wlr_output_commit_state(wlr_output, &state);
wlr_output_state_finish(&state);
if (!committed) {
wlr_log(WLR_ERROR, "Failed to commit init state for output %s",
wlr_output->name);
return;
}
LunarWM_Output *output = calloc(1, sizeof(*output));
if (!output) {
wlr_log(WLR_ERROR, "Out of memory creating output state");
return;
}
output->wm = wm;
output->wlr_output = wlr_output;
output->frame.notify = handle_output_frame;
wl_signal_add(&wlr_output->events.frame, &output->frame);
output->destroy.notify = handle_output_destroy;
wl_signal_add(&wlr_output->events.destroy, &output->destroy);
vector_add(&wm->wayland.v_outputs, output);
wlr_output_schedule_frame(wlr_output);
}
bool LunarWM_wayland_init(LunarWM *this)
{
wlr_log_init(WLR_DEBUG, nullptr);
this->wayland.v_toplevels = vector_create();
this->wayland.v_outputs = vector_create();
this->wayland.display = wl_display_create();
if (this->wayland.display == nullptr) {
@@ -1587,6 +1733,10 @@ bool LunarWM_wayland_init(LunarWM *this)
wl_list_init(&this->wayland.keyboards);
wl_list_init(&this->wayland.pointers);
this->wayland.new_output_listener.notify = handle_new_output;
wl_signal_add(&this->wayland.backend->events.new_output,
&this->wayland.new_output_listener);
this->wayland.new_input_listener.notify = new_input_listener_notify;
wl_signal_add(&this->wayland.backend->events.new_input,
&this->wayland.new_input_listener);
@@ -1616,6 +1766,20 @@ void LunarWM_wayland_cleanup(LunarWM *this)
this->wayland.custom_out_hud = NULL;
}
if (this->wayland.new_output_listener.link.prev
|| this->wayland.new_output_listener.link.next) {
wl_list_remove(&this->wayland.new_output_listener.link);
this->wayland.new_output_listener.notify = NULL;
}
if (this->wayland.v_outputs) {
for (size_t i = 0; i < vector_size(this->wayland.v_outputs); ++i) {
destroy_output(this->wayland.v_outputs[i]);
}
vector_free(this->wayland.v_outputs);
this->wayland.v_outputs = NULL;
}
if (this->wayland.xwayland) {
if (this->wayland.xwayland_new_surface.link.prev
|| this->wayland.xwayland_new_surface.link.next) {