From 39bf157ffd064720bd625f0dec08225642416a29 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Fri, 14 Apr 2023 15:53:20 +0200 Subject: [PATCH 01/37] refactor: refactor code --- src/popup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/popup.c b/src/popup.c index 7df675c0..0ee8d510 100644 --- a/src/popup.c +++ b/src/popup.c @@ -26,7 +26,6 @@ static void popup_damage(struct xdg_popup *xdg_popup, bool whole); struct xdg_popup *create_popup(struct monitor *m, struct wlr_xdg_popup *xdg_popup, struct wlr_box parent_geom, struct container* toplevel) { - struct xdg_popup *popup = xdg_popup->base->data = calloc(1, sizeof(*popup)); popup->xdg = xdg_popup; popup->toplevel = toplevel; @@ -38,8 +37,11 @@ struct xdg_popup *create_popup(struct monitor *m, struct wlr_xdg_popup *xdg_popu box.height = m->geom.height; wlr_xdg_popup_unconstrain_from_box(popup->xdg, &box); + printf("parent_geom.x: %i\n", parent_geom.x); + printf("parent_geom.y: %i\n", parent_geom.y); + printf("parent_geom.width: %i\n", parent_geom.width); // the root window may be resized. This must be adjusted - popup->geom.x = xdg_popup->current.geometry.x + parent_geom.x; + popup->geom.x = xdg_popup->current.geometry.x + parent_geom.x + 100; popup->geom.y = xdg_popup->current.geometry.y + parent_geom.y; popup->geom.width = xdg_popup->current.geometry.width; popup->geom.height = xdg_popup->current.geometry.height; From afeebce4c595680321c7ad8860e86f86a2e6e3f0 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Fri, 14 Apr 2023 15:53:51 +0200 Subject: [PATCH 02/37] refactor: rename _relative -> _local --- include/container.h | 4 ++-- src/container.c | 8 ++++---- src/cursor.c | 8 ++++---- src/popup.c | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/container.h b/include/container.h index 350e68cc..b27cc6f5 100644 --- a/include/container.h +++ b/include/container.h @@ -168,8 +168,8 @@ void container_resize_with_cursor(struct cursor *cursor); struct monitor *container_get_monitor(struct container *con); -int absolute_x_to_container_relative(struct wlr_box geom, int x); -int absolute_y_to_container_relative(struct wlr_box geom, int y); +int absolute_x_to_container_local(struct wlr_box geom, int x); +int absolute_y_to_container_local(struct wlr_box geom, int y); int get_position_in_container_focus_stack(struct container *con); int get_position_in_container_stack(struct container *con); diff --git a/src/container.c b/src/container.c index 9fa4dc0e..2277da07 100644 --- a/src/container.c +++ b/src/container.c @@ -1174,8 +1174,8 @@ void resize_container(struct container *con, struct wlr_cursor *cursor, int offs struct wlr_box geom = container_get_current_geom(con); - geom.width = absolute_x_to_container_relative(geom, cursor->x - offsetx); - geom.height = absolute_y_to_container_relative(geom, cursor->y - offsety); + geom.width = absolute_x_to_container_local(geom, cursor->x - offsetx); + geom.height = absolute_y_to_container_local(geom, cursor->y - offsety); if (con->on_scratchpad) { remove_container_from_scratchpad(con); @@ -1283,12 +1283,12 @@ struct monitor *container_get_monitor(struct container *con) return m; } -inline int absolute_x_to_container_relative(struct wlr_box geom, int x) +inline int absolute_x_to_container_local(struct wlr_box geom, int x) { return x - geom.x; } -inline int absolute_y_to_container_relative(struct wlr_box geom, int y) +inline int absolute_y_to_container_local(struct wlr_box geom, int y) { return y - geom.y; } diff --git a/src/cursor.c b/src/cursor.c index d93f60c9..269bf774 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -318,8 +318,8 @@ void focus_under_cursor(struct cursor *cursor, uint32_t time) struct container *focus_con = xy_to_container(cursorx, cursory); if (!is_popup_under_cursor && focus_con) { final_focus_surface = wlr_surface_surface_at(get_wlrsurface(focus_con->client), - absolute_x_to_container_relative(container_get_current_geom(focus_con), cursorx), - absolute_y_to_container_relative(container_get_current_geom(focus_con), cursory), + absolute_x_to_container_local(container_get_current_geom(focus_con), cursorx), + absolute_y_to_container_local(container_get_current_geom(focus_con), cursory), &sx, &sy); } @@ -478,8 +478,8 @@ void move_resize(struct cursor *cursor, int ui) switch (cursor->cursor_mode = ui) { case CURSOR_MOVE: wlr_xcursor_manager_set_cursor_image(cursor->xcursor_mgr, "fleur", wlr_cursor); - offsetx = absolute_x_to_container_relative(grabc_geom, wlr_cursor->x); - offsety = absolute_y_to_container_relative(grabc_geom, wlr_cursor->y); + offsetx = absolute_x_to_container_local(grabc_geom, wlr_cursor->x); + offsety = absolute_y_to_container_local(grabc_geom, wlr_cursor->y); break; case CURSOR_RESIZE: /* Doesn't work for X11 output - the next absolute motion event diff --git a/src/popup.c b/src/popup.c index 0ee8d510..c5e843a0 100644 --- a/src/popup.c +++ b/src/popup.c @@ -143,15 +143,15 @@ struct wlr_surface *get_popup_surface_under_cursor(struct cursor *cursor, double con->client->surface.xdg, /* absolute mouse position to relative in regards to * the client */ - absolute_x_to_container_relative(con_geom, cursorx), - absolute_y_to_container_relative(con_geom, cursory), + absolute_x_to_container_local(con_geom, cursorx), + absolute_y_to_container_local(con_geom, cursory), sx, sy); break; case LAYER_SHELL: surface = wlr_layer_surface_v1_surface_at( con->client->surface.layer, - absolute_x_to_container_relative(con_geom, cursorx), - absolute_y_to_container_relative(con_geom, cursory), + absolute_x_to_container_local(con_geom, cursorx), + absolute_y_to_container_local(con_geom, cursory), sx, sy); break; default: From 78a90ff445ae6634985e18806d248b5bd66cc756 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 01:59:04 +0200 Subject: [PATCH 03/37] fix stuff --- include/container.h | 2 +- include/popup.h | 5 ++++ src/container.c | 34 +++++++++---------------- src/popup.c | 60 +++++++++++++++++++++++++++++++++----------- src/render/render.c | 31 +++++++++++++++++++++-- src/tile/tileUtils.c | 10 +++++--- 6 files changed, 99 insertions(+), 43 deletions(-) diff --git a/include/container.h b/include/container.h index b27cc6f5..008b391e 100644 --- a/include/container.h +++ b/include/container.h @@ -83,7 +83,7 @@ struct wlr_box get_monitor_local_box(struct wlr_box box, struct monitor *m); struct wlr_fbox lua_togeometry(lua_State *L); void ack_configure(struct wl_listener *listener, void *data); -struct wlr_box apply_bounds(struct container *con, struct wlr_box bbox); +void apply_bounds(struct wlr_box *geom, struct wlr_box box); void commit_notify(struct wl_listener *listener, void *data); void configure_notify(struct wl_listener *listener, void *data); void container_damage_borders_at_monitor(struct container *con, struct monitor *m); diff --git a/include/popup.h b/include/popup.h index 03975fc6..4921525d 100644 --- a/include/popup.h +++ b/include/popup.h @@ -25,4 +25,9 @@ void destroy_popups(); struct wlr_surface *get_popup_surface_under_cursor(struct cursor *cursor, double *sx, double *sy); struct xdg_popup *get_latest_popup(); bool popups_exist(); + +void popup_set_x(struct xdg_popup *popup, int x); +void popup_set_y(struct xdg_popup *popup, int y); +void popup_set_width(struct xdg_popup *popup, int width); +void popup_set_height(struct xdg_popup *popup, int height); #endif /* POPUP_H */ diff --git a/src/container.c b/src/container.c index 2277da07..2c694583 100644 --- a/src/container.c +++ b/src/container.c @@ -402,30 +402,20 @@ struct wlr_fbox lua_togeometry(lua_State *L) } // TODO: look if this function is still needed -struct wlr_box apply_bounds(struct container *con, struct wlr_box box) +void apply_bounds(struct wlr_box *geom, struct wlr_box box) { /* set minimum possible */ - struct wlr_box con_geom = container_get_current_content_geom(con); - - if (container_is_tiled(con)) - return con_geom; - - con_geom.width = MAX(MIN_CONTAINER_WIDTH, con_geom.width); - con_geom.height = MAX(MIN_CONTAINER_HEIGHT, con_geom.height); - - struct direction_value bw = container_get_border_width(con); - - if (con_geom.x >= box.x + box.width) - con_geom.x = box.x + box.width - con_geom.width; - if (con_geom.y >= box.y + box.height) - con_geom.y = box.y + box.height - con_geom.height; - if (con_geom.x + con_geom.width + bw.left + bw.right <= box.x) - con_geom.x = box.x; - if (con_geom.y + con_geom.height + bw.top + bw.bottom <= box.y) - con_geom.y = box.y; - - container_set_current_content_geom(con, con_geom); - return con_geom; + geom->width = MAX(MIN_CONTAINER_WIDTH, geom->width); + geom->height = MAX(MIN_CONTAINER_HEIGHT, geom->height); + + if (geom->x >= box.x + box.width) + geom->x = box.x + box.width - geom->width; + if (geom->y >= box.y + box.height) + geom->y = box.y + box.height - geom->height; + if (geom->x + geom->width <= box.x) + geom->x = box.x; + if (geom->y + geom->height <= box.y) + geom->y = box.y; } void commit_notify(struct wl_listener *listener, void *data) diff --git a/src/popup.c b/src/popup.c index c5e843a0..9633e0a0 100644 --- a/src/popup.c +++ b/src/popup.c @@ -30,21 +30,11 @@ struct xdg_popup *create_popup(struct monitor *m, struct wlr_xdg_popup *xdg_popu popup->xdg = xdg_popup; popup->toplevel = toplevel; - struct wlr_box box = xdg_popup->current.geometry; - box.x = 0; - box.y = 0; - box.width = m->geom.width; - box.height = m->geom.height; - - wlr_xdg_popup_unconstrain_from_box(popup->xdg, &box); - printf("parent_geom.x: %i\n", parent_geom.x); - printf("parent_geom.y: %i\n", parent_geom.y); - printf("parent_geom.width: %i\n", parent_geom.width); + // TODO: what does this exactly do? + // struct wlr_box output_geom = monitor_get_active_geom(m); + // wlr_xdg_popup_unconstrain_from_box(xdg_popup, &output_geom); + // the root window may be resized. This must be adjusted - popup->geom.x = xdg_popup->current.geometry.x + parent_geom.x + 100; - popup->geom.y = xdg_popup->current.geometry.y + parent_geom.y; - popup->geom.width = xdg_popup->current.geometry.width; - popup->geom.height = xdg_popup->current.geometry.height; popup->m = m; LISTEN(&popup->xdg->base->events.map, &popup->map, popup_handle_map); @@ -76,7 +66,27 @@ static void popup_handle_commit(struct wl_listener *listener, void *data) static void popup_handle_map(struct wl_listener *listener, void *data) { struct xdg_popup *popup = wl_container_of(listener, popup, map); - popup_damage(popup, true); + + struct wlr_xdg_popup *xdg_popup = popup->xdg; + + double sx, sy; + wlr_xdg_popup_get_position(xdg_popup, &sx, &sy); + int toplevel_sx, toplevel_sy; + wlr_xdg_popup_get_toplevel_coords(xdg_popup, sx, sy, &toplevel_sx, &toplevel_sy); + + struct container *toplevel = popup->toplevel; + struct wlr_box toplevel_geom = container_get_current_geom(toplevel); + + // the root window may be resized. This must be adjusted + popup_set_x(popup, toplevel_sx + toplevel_geom.x); + popup_set_y(popup, toplevel_sy + toplevel_geom.y); + popup_set_width(popup, xdg_popup->current.geometry.width); + popup_set_height(popup, xdg_popup->current.geometry.height); + + struct monitor *m = server_get_selected_monitor(); + struct wlr_box output_geom = monitor_get_active_geom(m); + + apply_bounds(&popup->geom, output_geom); popup->commit.notify = popup_handle_commit; wl_signal_add(&popup->xdg->base->surface->events.commit, &popup->commit); @@ -184,3 +194,23 @@ inline bool popups_exist() { return server.popups->len > 0; } + +void popup_set_x(struct xdg_popup *popup, int x) +{ + popup->geom.x = x; +} + +void popup_set_y(struct xdg_popup *popup, int y) +{ + popup->geom.y = y; +} + +void popup_set_width(struct xdg_popup *popup, int width) +{ + popup->geom.width = width; +} + +void popup_set_height(struct xdg_popup *popup, int height) +{ + popup->geom.height = height; +} diff --git a/src/render/render.c b/src/render/render.c index b8568d84..ffb534bd 100644 --- a/src/render/render.c +++ b/src/render/render.c @@ -72,6 +72,16 @@ static bool intersects_with_output(struct monitor *m, return wlr_box_intersection(&intersection, &output_box, surface_box); } +/* + * output_for_each_surface_iterator is a callback for rendering surfaces on an + * output. Called by wlr_surface_for_each_surface in rendering order. + * + * Params: + * - surface: The wlr_surface to be rendered on the output. + * - sx: The x-coordinate of the surface relative to the output. + * - sy: The y-coordinate of the surface relative to the output. + * - user_data: A pointer to user-specific data to be used in the callback. + */ static void output_for_each_surface_iterator(struct wlr_surface *surface, int sx, int sy, void *user_data) { struct surface_iterator_data *data = user_data; @@ -109,6 +119,11 @@ static void render_texture(struct wlr_output *wlr_output, pixman_region32_fini(&damage); } +/* + * render_surface_iterator is a callback for rendering surfaces on an output. + * It sets up the proper transformations and scales, then calls the render + * function. Used by wlr_output_render_software_with_damage. + */ static void render_surface_iterator(struct monitor *m, struct wlr_surface *surface, struct wlr_box *box, void *data) { @@ -147,6 +162,12 @@ static void render_surface_iterator(struct monitor *m, struct wlr_surface *surfa wlr_surface_send_frame_done(surface, &now); } +static void render_surface_iterator_tmp(struct monitor *m, struct wlr_surface *surface, + struct wlr_box *box, void *data) +{ + render_surface_iterator(m, surface, box, data); +} + static void damage_surface_iterator(struct monitor *m, struct wlr_surface *surface, struct wlr_box *box, void *user_data) @@ -359,9 +380,15 @@ static void render_popups(struct monitor *m, pixman_region32_t *output_damage) // popups are weird and require to use the dimensions of the surface // instead - popup->geom.width = surface->current.width; - popup->geom.height = surface->current.height; + popup_set_width(popup, surface->current.width); + popup_set_height(popup, surface->current.height); + struct wlr_box obox = popup->geom; + // printf("render popup: %i\n", i); + // printf("obox.x: %i\n", obox.x); + // printf("obox.y: %i\n", obox.y); + // printf("obox.width: %i\n", obox.width); + // printf("obox.height: %i\n", obox.height); struct render_texture_data render_data; render_data.alpha = 1.0f; diff --git a/src/tile/tileUtils.c b/src/tile/tileUtils.c index 4c4b2248..f22a3ba6 100644 --- a/src/tile/tileUtils.c +++ b/src/tile/tileUtils.c @@ -299,9 +299,13 @@ void container_update_size(struct container *con) con->client->resized = true; struct wlr_box con_geom = container_get_current_content_geom(con); - struct wlr_box output_geom; - wlr_output_layout_get_box(server.output_layout, NULL, &output_geom); - con_geom = apply_bounds(con, output_geom); + + if (!container_is_tiled(con)) { + struct monitor *m = server_get_selected_monitor(); + struct wlr_box output_geom = monitor_get_active_geom(m); + apply_bounds(&con_geom, output_geom); + container_set_current_geom(con, con_geom); + } /* wlroots makes this a no-op if size hasn't changed */ switch (con->client->type) { From 0f615b8906dc94ae18f9b2ed5abb81ec283aa43c Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 02:33:48 +0200 Subject: [PATCH 04/37] feat: fix popups --- include/popup.h | 3 ++- src/client.c | 2 +- src/popup.c | 31 ++++++++++++++++++++++++------- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/include/popup.h b/include/popup.h index 4921525d..f475948d 100644 --- a/include/popup.h +++ b/include/popup.h @@ -10,6 +10,7 @@ struct xdg_popup { struct container *toplevel; struct wlr_box geom; struct monitor *m; + void *parent; struct wl_listener map; struct wl_listener unmap; @@ -19,7 +20,7 @@ struct xdg_popup { }; struct xdg_popup *create_popup(struct monitor *m, struct wlr_xdg_popup *xdg_popup, - struct wlr_box parent_geom, struct container* toplevel); + void *parent, struct container* toplevel); void popup_handle_destroy(struct wl_listener *listener, void *data); void destroy_popups(); struct wlr_surface *get_popup_surface_under_cursor(struct cursor *cursor, double *sx, double *sy); diff --git a/src/client.c b/src/client.c index 2c26edd9..7bc12997 100644 --- a/src/client.c +++ b/src/client.c @@ -208,7 +208,7 @@ void client_handle_new_popup(struct wl_listener *listener, void *data) struct container *con = client->con; struct monitor *m = container_get_monitor(con); - create_popup(m, xdg_popup, container_get_current_geom(con), con); + create_popup(m, xdg_popup, con, con); } void client_handle_set_title(struct wl_listener *listener, void *data) diff --git a/src/popup.c b/src/popup.c index 9633e0a0..e750931d 100644 --- a/src/popup.c +++ b/src/popup.c @@ -24,11 +24,12 @@ static void popup_handle_unmap(struct wl_listener *listener, void *data); static void popup_damage(struct xdg_popup *xdg_popup, bool whole); struct xdg_popup *create_popup(struct monitor *m, struct wlr_xdg_popup *xdg_popup, - struct wlr_box parent_geom, struct container* toplevel) + void *parent, struct container* toplevel) { struct xdg_popup *popup = xdg_popup->base->data = calloc(1, sizeof(*popup)); popup->xdg = xdg_popup; popup->toplevel = toplevel; + popup->parent = parent; // TODO: what does this exactly do? // struct wlr_box output_geom = monitor_get_active_geom(m); @@ -71,15 +72,31 @@ static void popup_handle_map(struct wl_listener *listener, void *data) double sx, sy; wlr_xdg_popup_get_position(xdg_popup, &sx, &sy); - int toplevel_sx, toplevel_sy; - wlr_xdg_popup_get_toplevel_coords(xdg_popup, sx, sy, &toplevel_sx, &toplevel_sy); + printf("new position: %f:%f\n", sx, sy); + + int offset_x = 0; + int offset_y = 0; + + for (struct xdg_popup *curr_popup = popup; + curr_popup->parent != popup->toplevel; + curr_popup = popup->parent) { + struct xdg_popup *parent_popup = curr_popup->parent; + double sx, sy; + wlr_xdg_popup_get_position(parent_popup->xdg, &sx, &sy); + offset_x += sx; + offset_y += sy; + } struct container *toplevel = popup->toplevel; - struct wlr_box toplevel_geom = container_get_current_geom(toplevel); + struct wlr_box toplevel_geom = container_get_current_content_geom(toplevel); + + offset_x += toplevel_geom.x; + offset_y += toplevel_geom.y; + // the root window may be resized. This must be adjusted - popup_set_x(popup, toplevel_sx + toplevel_geom.x); - popup_set_y(popup, toplevel_sy + toplevel_geom.y); + popup_set_x(popup, offset_x + sx); + popup_set_y(popup, offset_y + sy); popup_set_width(popup, xdg_popup->current.geometry.width); popup_set_height(popup, xdg_popup->current.geometry.height); @@ -118,7 +135,7 @@ static void popup_handle_new_popup(struct wl_listener *listener, void *data) struct wlr_xdg_popup *xdg_popup = data; create_popup(parent_popup->m, xdg_popup, - parent_popup->geom, parent_popup->toplevel); + parent_popup, parent_popup->toplevel); } void popup_handle_destroy(struct wl_listener *listener, void *data) From b5ed935fb4f1cf56930ad58509b28031e5e0ae50 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 02:45:08 +0200 Subject: [PATCH 05/37] fix: fix weird glitches --- src/popup.c | 5 ----- src/tile/tileUtils.c | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/popup.c b/src/popup.c index e750931d..38420051 100644 --- a/src/popup.c +++ b/src/popup.c @@ -100,11 +100,6 @@ static void popup_handle_map(struct wl_listener *listener, void *data) popup_set_width(popup, xdg_popup->current.geometry.width); popup_set_height(popup, xdg_popup->current.geometry.height); - struct monitor *m = server_get_selected_monitor(); - struct wlr_box output_geom = monitor_get_active_geom(m); - - apply_bounds(&popup->geom, output_geom); - popup->commit.notify = popup_handle_commit; wl_signal_add(&popup->xdg->base->surface->events.commit, &popup->commit); } diff --git a/src/tile/tileUtils.c b/src/tile/tileUtils.c index f22a3ba6..56d9047c 100644 --- a/src/tile/tileUtils.c +++ b/src/tile/tileUtils.c @@ -298,7 +298,7 @@ void container_update_size(struct container *con) { con->client->resized = true; - struct wlr_box con_geom = container_get_current_content_geom(con); + struct wlr_box con_geom = container_get_current_geom(con); if (!container_is_tiled(con)) { struct monitor *m = server_get_selected_monitor(); From 6e37c41598a57be2a07df436c3dd74f8ffde5c08 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 02:46:05 +0200 Subject: [PATCH 06/37] feat: implement all the rest functions --- src/popup.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/popup.c b/src/popup.c index 38420051..509832fc 100644 --- a/src/popup.c +++ b/src/popup.c @@ -100,6 +100,11 @@ static void popup_handle_map(struct wl_listener *listener, void *data) popup_set_width(popup, xdg_popup->current.geometry.width); popup_set_height(popup, xdg_popup->current.geometry.height); + // TODO: either use this or use actual xdg constraints + struct monitor *m = server_get_selected_monitor(); + struct wlr_box output_geom = monitor_get_active_geom(m); + apply_bounds(&popup->geom, output_geom); + popup->commit.notify = popup_handle_commit; wl_signal_add(&popup->xdg->base->surface->events.commit, &popup->commit); } From aed76b4a34936bf6e1091da8a192525e6c62527a Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 02:51:07 +0200 Subject: [PATCH 07/37] fix: fix infinit loop in popups --- src/popup.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/popup.c b/src/popup.c index 509832fc..ea58eb94 100644 --- a/src/popup.c +++ b/src/popup.c @@ -73,14 +73,12 @@ static void popup_handle_map(struct wl_listener *listener, void *data) double sx, sy; wlr_xdg_popup_get_position(xdg_popup, &sx, &sy); - printf("new position: %f:%f\n", sx, sy); - int offset_x = 0; int offset_y = 0; for (struct xdg_popup *curr_popup = popup; - curr_popup->parent != popup->toplevel; - curr_popup = popup->parent) { + curr_popup->parent != curr_popup->toplevel; + curr_popup = curr_popup->parent) { struct xdg_popup *parent_popup = curr_popup->parent; double sx, sy; wlr_xdg_popup_get_position(parent_popup->xdg, &sx, &sy); From 9504bb218bbf880206b9f094af71b4e961699283 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 03:12:58 +0200 Subject: [PATCH 08/37] fix: fix crash on launching and running morgen --- config/layouts/tmp/init.lua | 1 - src/render/render.c | 9 ++------- src/xdg_shell.c | 5 +++-- src/xwayland.c | 1 + 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/config/layouts/tmp/init.lua b/config/layouts/tmp/init.lua index f50e507c..06026315 100644 --- a/config/layouts/tmp/init.lua +++ b/config/layouts/tmp/init.lua @@ -123,4 +123,3 @@ local resize_groups = {} resize_groups[1] = {{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}} layout:set_resize_data(resize_groups) opt.resize_direction = Direction.all -print("works") diff --git a/src/render/render.c b/src/render/render.c index ffb534bd..56f2ecf0 100644 --- a/src/render/render.c +++ b/src/render/render.c @@ -378,17 +378,12 @@ static void render_popups(struct monitor *m, pixman_region32_t *output_damage) struct xdg_popup *popup = g_ptr_array_index(server.popups, i); struct wlr_surface *surface = popup->xdg->base->surface; - // popups are weird and require to use the dimensions of the surface - // instead + // FIXME: popups are weird and require to use the dimensions of the + // surface instead popup_set_width(popup, surface->current.width); popup_set_height(popup, surface->current.height); struct wlr_box obox = popup->geom; - // printf("render popup: %i\n", i); - // printf("obox.x: %i\n", obox.x); - // printf("obox.y: %i\n", obox.y); - // printf("obox.width: %i\n", obox.width); - // printf("obox.height: %i\n", obox.height); struct render_texture_data render_data; render_data.alpha = 1.0f; diff --git a/src/xdg_shell.c b/src/xdg_shell.c index 60a3ece6..53562504 100644 --- a/src/xdg_shell.c +++ b/src/xdg_shell.c @@ -76,10 +76,11 @@ void destroy_notify(struct wl_listener *listener, void *data) wl_list_remove(&c->map.link); wl_list_remove(&c->commit.link); - wl_list_remove(&c->unmap.link); - wl_list_remove(&c->destroy.link); wl_list_remove(&c->configure.link); wl_list_remove(&c->ack_configure.link); + wl_list_remove(&c->unmap.link); + wl_list_remove(&c->destroy.link); + wl_list_remove(&c->new_subsurface.link); wl_list_remove(&c->set_title.link); wl_list_remove(&c->set_app_id.link); diff --git a/src/xwayland.c b/src/xwayland.c index 68863894..b060a450 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -76,6 +76,7 @@ void destroy_notifyx11(struct wl_listener *listener, void *data) wl_list_remove(&c->destroy.link); wl_list_remove(&c->set_title.link); wl_list_remove(&c->set_app_id.link); + wl_list_remove(&c->activate.link); destroy_client(c); } From caf912759567c926ee43c5cd0263408fa7bf7889 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 04:44:13 +0200 Subject: [PATCH 09/37] feat: add basic structure for scene api --- include/monitor.h | 3 +++ include/server.h | 14 +++++++++++++ src/container.c | 2 +- src/monitor.c | 19 +++++++++++++----- src/render/render.c | 48 ++++++++++++++++++++++---------------------- src/root.c | 6 +++--- src/server.c | 32 +++++++++++++++++++++++++++++ src/tile/tileUtils.c | 2 +- src/xdg_shell.c | 1 + 9 files changed, 93 insertions(+), 34 deletions(-) diff --git a/include/monitor.h b/include/monitor.h index fb99a05d..4271ad60 100644 --- a/include/monitor.h +++ b/include/monitor.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "server.h" #include "bitset/bitset.h" @@ -22,6 +23,8 @@ struct monitor { struct root *root; float scale; + struct wlr_scene_output *scene_output; + int tag_id; }; diff --git a/include/server.h b/include/server.h index 57ed4a99..a00c69c2 100644 --- a/include/server.h +++ b/include/server.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "cursor.h" #include "layout.h" @@ -22,6 +23,16 @@ #include "utils/coreUtils.h" #include "bitset/bitset.h" +struct scene_surface { + struct wlr_surface *wlr; + struct wlr_scene_surface *scene_surface; + struct wlr_scene_rect *border; + struct wl_list link; + + struct wl_listener commit; + struct wl_listener destroy; +}; + struct server { bool is_running; uv_loop_t *uv_loop; @@ -44,6 +55,9 @@ struct server { struct event_handler *event_handler; + struct wlr_scene *scene; + struct wl_listener new_surface; + struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr; struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr; struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr; diff --git a/src/container.c b/src/container.c index 2c694583..8ab357e5 100644 --- a/src/container.c +++ b/src/container.c @@ -209,7 +209,7 @@ void container_damage_borders_at_monitor(struct container *con, struct monitor * .height = border.height, }; scale_box(&obox, m->wlr_output->scale); - wlr_output_damage_add_box(m->damage, &obox); + // wlr_output_damage_add_box(m->damage, &obox); } } diff --git a/src/monitor.c b/src/monitor.c index 8bed65c6..3c88b76b 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -53,9 +53,10 @@ void create_monitor(struct wl_listener *listener, void *data) /* damage tracking must be initialized before setting the tag because * it to damage a region */ - m->damage = wlr_output_damage_create(m->wlr_output); - m->damage_frame.notify = handle_output_damage_frame; - wl_signal_add(&m->damage->events.frame, &m->damage_frame); + // TODO: do we need it for sceengraph? + // m->damage = wlr_output_damage_create(m->wlr_output); + // m->damage_frame.notify = handle_output_damage_frame; + // wl_signal_add(&m->damage->events.frame, &m->damage_frame); m->frame.notify = handle_output_frame; wl_signal_add(&m->wlr_output->events.frame, &m->frame); @@ -82,6 +83,8 @@ void create_monitor(struct wl_listener *listener, void *data) wlr_output_enable(output, true); + m->scene_output = wlr_scene_output_create(server.scene, output); + wlr_output_layout_get_box(server.output_layout, m->wlr_output, &m->geom); m->root = create_root(m, m->geom); @@ -144,11 +147,17 @@ void create_output(struct wlr_backend *backend, void *data) /* #endif */ } -int i = 0; static void handle_output_frame(struct wl_listener *listener, void *data) { - struct monitor *m = wl_container_of(listener, m, damage_frame); + struct monitor *m = wl_container_of(listener, m, frame); + + if (!wlr_scene_output_commit(m->scene_output)) { + return; + } + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + wlr_scene_output_send_frame_done(m->scene_output, &now); /* NOOP */ } diff --git a/src/render/render.c b/src/render/render.c index 56f2ecf0..e769407b 100644 --- a/src/render/render.c +++ b/src/render/render.c @@ -172,30 +172,30 @@ static void damage_surface_iterator(struct monitor *m, struct wlr_surface *surface, struct wlr_box *box, void *user_data) { - struct wlr_output *wlr_output = m->wlr_output; - bool whole = *(bool *) user_data; - struct wlr_box geom = *box; - - scale_box(&geom, wlr_output->scale); - - if (whole) { - wlr_output_damage_add_box(m->damage, &geom); - } else if (pixman_region32_not_empty(&surface->buffer_damage)) { - pixman_region32_t damage; - pixman_region32_init(&damage); - wlr_surface_get_effective_damage(surface, &damage); - - wlr_region_scale(&damage, &damage, wlr_output->scale); - if (ceil(wlr_output->scale) > surface->current.scale) { - /* When scaling up a surface it'll become - blurry, so we need to expand the damage - region. */ - wlr_region_expand(&damage, &damage, ceil(wlr_output->scale) - surface->current.scale); - } - pixman_region32_translate(&damage, geom.x, geom.y); - wlr_output_damage_add(m->damage, &damage); - pixman_region32_fini(&damage); - } + // struct wlr_output *wlr_output = m->wlr_output; + // bool whole = *(bool *) user_data; + // struct wlr_box geom = *box; + // + // scale_box(&geom, wlr_output->scale); + // + // if (whole) { + // wlr_output_damage_add_box(m->damage, &geom); + // } else if (pixman_region32_not_empty(&surface->buffer_damage)) { + // pixman_region32_t damage; + // pixman_region32_init(&damage); + // wlr_surface_get_effective_damage(surface, &damage); + // + // wlr_region_scale(&damage, &damage, wlr_output->scale); + // if (ceil(wlr_output->scale) > surface->current.scale) { + // /* When scaling up a surface it'll become + // blurry, so we need to expand the damage + // region. */ + // wlr_region_expand(&damage, &damage, ceil(wlr_output->scale) - surface->current.scale); + // } + // pixman_region32_translate(&damage, geom.x, geom.y); + // // wlr_output_damage_add(m->damage, &damage); + // pixman_region32_fini(&damage); + // } } void output_damage_surface(struct monitor *m, struct wlr_surface *surface, struct wlr_box *geom, bool whole) diff --git a/src/root.c b/src/root.c index eca609b2..08f6b06f 100644 --- a/src/root.c +++ b/src/root.c @@ -89,9 +89,9 @@ void root_damage_whole(struct root *root) { if (!root) return; - struct monitor *m = root->m; - struct wlr_box geom = get_monitor_local_box(root->geom, m); - wlr_output_damage_add_box(m->damage, &geom); + // struct monitor *m = root->m; + // struct wlr_box geom = get_monitor_local_box(root->geom, m); + // wlr_output_damage_add_box(m->damage, &geom); } static enum wlr_edges bar_get_direction(struct container *con) diff --git a/src/server.c b/src/server.c index 4bfcee0e..aa1415fb 100644 --- a/src/server.c +++ b/src/server.c @@ -402,6 +402,34 @@ static void _async_handler_function(struct uv_async_s *arg) free(data); } +static void surface_handle_commit(struct wl_listener *listener, void *data) { + struct scene_surface *surface = wl_container_of(listener, surface, commit); +} + +static void surface_handle_destroy(struct wl_listener *listener, void *data) { + struct scene_surface *surface = wl_container_of(listener, surface, destroy); + wlr_scene_node_destroy(&surface->scene_surface->buffer->node); + wlr_scene_node_destroy(&surface->border->node); + wl_list_remove(&surface->destroy.link); + free(surface); +} + +static void server_handle_new_surface(struct wl_listener *listener, void *data) +{ + struct server *server = wl_container_of(listener, server, new_surface); + struct wlr_surface *wlr_surface = data; + + struct scene_surface *surface = calloc(1, sizeof(struct scene_surface)); + surface->wlr = wlr_surface; + surface->commit.notify = surface_handle_commit; + wl_signal_add(&wlr_surface->events.commit, &surface->commit); + surface->destroy.notify = surface_handle_destroy; + wl_signal_add(&wlr_surface->events.destroy, &surface->destroy); + + surface->scene_surface = + wlr_scene_surface_create(&server->scene->tree, wlr_surface); +} + int setup_server(struct server *server) { server->uv_loop = uv_default_loop(); @@ -475,6 +503,10 @@ int setup_server(struct server *server) server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); + server->scene = wlr_scene_create(); + server->new_surface.notify = server_handle_new_surface; + wl_signal_add(&server->compositor->events.new_surface, &server->new_surface); + #ifdef JAPOKWM_HAS_XWAYLAND init_xwayland(server->wl_display, seat); #endif diff --git a/src/tile/tileUtils.c b/src/tile/tileUtils.c index 56d9047c..9a04d3e5 100644 --- a/src/tile/tileUtils.c +++ b/src/tile/tileUtils.c @@ -238,7 +238,7 @@ void arrange_monitor(struct monitor *m) arrange_containers(tag, active_geom, tiled_containers); g_ptr_array_unref(tiled_containers); - wlr_output_damage_add_whole(m->damage); + // wlr_output_damage_add_whole(m->damage); update_reduced_focus_stack(tag); tag_focus_most_recent_container(tag); } diff --git a/src/xdg_shell.c b/src/xdg_shell.c index 53562504..b6ebbbdf 100644 --- a/src/xdg_shell.c +++ b/src/xdg_shell.c @@ -37,6 +37,7 @@ static void getxdecomode(struct wl_listener *listener, void *data) void create_notify_xdg(struct wl_listener *listener, void *data) { + printf("create notify xdg\n"); /* This event is raised when wlr_xdg_shell receives a new xdg surface from a * client, either a toplevel (application window) or popup. */ struct wlr_xdg_surface *xdg_surface = data; From 0e3d91bbbedbe55da02529a3603c746a2918ff7f Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 04:53:53 +0200 Subject: [PATCH 10/37] fix stuff --- include/render/render.h | 34 --- include/utils/writeFile.h | 1 - src/container.c | 1 - src/cursor.c | 1 - src/layer_shell.c | 1 - src/main.c | 1 - src/monitor.c | 34 --- src/popup.c | 16 -- src/render/render.c | 453 -------------------------------------- src/server.c | 1 - 10 files changed, 543 deletions(-) delete mode 100644 include/render/render.h delete mode 100644 src/render/render.c diff --git a/include/render/render.h b/include/render/render.h deleted file mode 100644 index badfda33..00000000 --- a/include/render/render.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef RENDER_H -#define RENDER_H -#include "utils/coreUtils.h" -#include "client.h" -#include "monitor.h" -#include -#include -#include -#include -#include - -typedef void (*surface_iterator_func_t)(struct monitor *m, struct - wlr_surface *surface, struct wlr_box *box, void *user_data); - -struct surface_iterator_data { - surface_iterator_func_t user_iterator; - void *user_data; - - struct monitor *m; - - /* Output-local coordinates. */ - struct wlr_box render_box; -}; - -struct render_texture_data { - pixman_region32_t *output_damage; - float alpha; -}; - -void render_monitor(struct monitor *m, pixman_region32_t *damage); -void scale_box(struct wlr_box *box, float scale); -void output_damage_surface(struct monitor *m, struct wlr_surface *surface, - struct wlr_box *geom, bool whole); -#endif /* RENDER_H */ diff --git a/include/utils/writeFile.h b/include/utils/writeFile.h index 5cca7157..e282dbe3 100644 --- a/include/utils/writeFile.h +++ b/include/utils/writeFile.h @@ -6,7 +6,6 @@ #include #include "utils/stringUtils.h" -#include "render/render.h" int write_to_file(int fd, const char *content); void write_container_to_file(int fd, struct wlr_fbox box); diff --git a/src/container.c b/src/container.c index 8ab357e5..63cb1b46 100644 --- a/src/container.c +++ b/src/container.c @@ -15,7 +15,6 @@ #include "server.h" #include "monitor.h" #include "tile/tileUtils.h" -#include "render/render.h" #include "options.h" #include "utils/parseConfigUtils.h" #include "scratchpad.h" diff --git a/src/cursor.c b/src/cursor.c index 269bf774..71faa4ac 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -9,7 +9,6 @@ #include "keybinding.h" #include "monitor.h" #include "popup.h" -#include "render/render.h" #include "seat.h" #include "server.h" #include "tile/tileUtils.h" diff --git a/src/layer_shell.c b/src/layer_shell.c index 0cab3d2f..846b56b5 100644 --- a/src/layer_shell.c +++ b/src/layer_shell.c @@ -9,7 +9,6 @@ #include "server.h" #include "container.h" #include "tile/tileUtils.h" -#include "render/render.h" #include "input_manager.h" #include "root.h" #include "tagset.h" diff --git a/src/main.c b/src/main.c index f6eda9c6..27eb2e74 100644 --- a/src/main.c +++ b/src/main.c @@ -21,7 +21,6 @@ #include "keyboard.h" #include "layer_shell.h" -#include "render/render.h" #include "scratchpad.h" #include "server.h" #include "translationLayer.h" diff --git a/src/monitor.c b/src/monitor.c index 3c88b76b..ca81c1e5 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -10,7 +10,6 @@ #include #include "ipc-server.h" -#include "render/render.h" #include "server.h" #include "tile/tileUtils.h" #include "tag.h" @@ -23,7 +22,6 @@ #include "client.h" #include "container.h" -static void handle_output_damage_frame(struct wl_listener *listener, void *data); static void handle_output_frame(struct wl_listener *listener, void *data); static void handle_output_mode(struct wl_listener *listener, void *data); static void monitor_get_initial_tag(struct monitor *m, GList *tags); @@ -53,10 +51,6 @@ void create_monitor(struct wl_listener *listener, void *data) /* damage tracking must be initialized before setting the tag because * it to damage a region */ - // TODO: do we need it for sceengraph? - // m->damage = wlr_output_damage_create(m->wlr_output); - // m->damage_frame.notify = handle_output_damage_frame; - // wl_signal_add(&m->damage->events.frame, &m->damage_frame); m->frame.notify = handle_output_frame; wl_signal_add(&m->wlr_output->events.frame, &m->frame); @@ -161,34 +155,6 @@ static void handle_output_frame(struct wl_listener *listener, void *data) /* NOOP */ } -int j = 0; -static void handle_output_damage_frame(struct wl_listener *listener, void *data) -{ - struct monitor *m = wl_container_of(listener, m, damage_frame); - - if (!m->wlr_output->enabled) { - return; - } - - /* Check if we can scan-out the primary view. */ - pixman_region32_t frame_damage; - pixman_region32_init(&frame_damage); - bool needs_frame; - if (!wlr_output_damage_attach_render(m->damage, &needs_frame, &frame_damage)) { - goto damage_finish; - } - - if (!needs_frame) { - wlr_output_rollback(m->wlr_output); - goto damage_finish; - } - - render_monitor(m, &frame_damage); - -damage_finish: - pixman_region32_fini(&frame_damage); -} - static void handle_output_mode(struct wl_listener *listener, void *data) { struct monitor *m = wl_container_of(listener, m, mode); diff --git a/src/popup.c b/src/popup.c index ea58eb94..56f14508 100644 --- a/src/popup.c +++ b/src/popup.c @@ -9,7 +9,6 @@ #include "client.h" #include "container.h" #include "monitor.h" -#include "render/render.h" #include "root.h" #include "server.h" #include "utils/coreUtils.h" @@ -21,7 +20,6 @@ static void destroy_popup(struct xdg_popup *xdg_popup); static void popup_handle_commit(struct wl_listener *listener, void *data); static void popup_handle_map(struct wl_listener *listener, void *data); static void popup_handle_unmap(struct wl_listener *listener, void *data); -static void popup_damage(struct xdg_popup *xdg_popup, bool whole); struct xdg_popup *create_popup(struct monitor *m, struct wlr_xdg_popup *xdg_popup, void *parent, struct container* toplevel) @@ -61,7 +59,6 @@ static void destroy_popup(struct xdg_popup *xdg_popup) static void popup_handle_commit(struct wl_listener *listener, void *data) { struct xdg_popup *popup = wl_container_of(listener, popup, commit); - popup_damage(popup, false); } static void popup_handle_map(struct wl_listener *listener, void *data) @@ -111,19 +108,6 @@ static void popup_handle_unmap(struct wl_listener *listener, void *data) { struct xdg_popup *popup = wl_container_of(listener, popup, unmap); wl_list_remove(&popup->commit.link); - popup_damage(popup, true); -} - -static void popup_damage(struct xdg_popup *xdg_popup, bool whole) -{ - if (!xdg_popup) - return; - - struct wlr_xdg_popup *popup = xdg_popup->xdg; - struct wlr_surface *surface = popup->base->surface; - struct monitor *m = xdg_popup->m; - - output_damage_surface(m, surface, &xdg_popup->geom, whole); } static void popup_handle_new_popup(struct wl_listener *listener, void *data) diff --git a/src/render/render.c b/src/render/render.c deleted file mode 100644 index e769407b..00000000 --- a/src/render/render.c +++ /dev/null @@ -1,453 +0,0 @@ -#include "render/render.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "container.h" -#include "client.h" -#include "list_sets/container_stack_set.h" -#include "monitor.h" -#include "popup.h" -#include "root.h" -#include "server.h" -#include "tile/tileUtils.h" -#include "utils/gapUtils.h" -#include "tag.h" -#include "tagset.h" - -static void render_stack(struct monitor *m, pixman_region32_t *output_damage); -static void scissor_output(struct wlr_output *output, pixman_box32_t *rect); -static void render_texture(struct wlr_output *wlr_output, - pixman_region32_t *output_damage, struct wlr_texture *texture, - const struct wlr_box *box, float alpha); - -/* _box.x and .y are expected to be layout-local - _box.width and .height are expected to be output-buffer-local */ -void render_rect(struct monitor *m, pixman_region32_t *output_damage, - const struct wlr_box *_box, const struct color color) { - struct wlr_output *wlr_output = m->wlr_output; - struct wlr_renderer *renderer = server.renderer; - - struct wlr_box box; - memcpy(&box, _box, sizeof(struct wlr_box)); - - pixman_region32_t damage; - pixman_region32_init(&damage); - pixman_region32_union_rect(&damage, &damage, box.x, box.y, - box.width, box.height); - pixman_region32_intersect(&damage, &damage, output_damage); - bool damaged = pixman_region32_not_empty(&damage); - if (!damaged) { - pixman_region32_fini(&damage); - return; - } - - int nrects; - pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); - for (int i = 0; i < nrects; ++i) { - scissor_output(wlr_output, &rects[i]); - float wlr_color[4]; - color_to_wlr_color(wlr_color, color); - wlr_render_rect(renderer, &box, wlr_color, - wlr_output->transform_matrix); - } -} - -static bool intersects_with_output(struct monitor *m, - struct wlr_output_layout *output_layout, struct wlr_box *surface_box) -{ - /* Since the surface_box's x- and y-coordinates are already output local, - * the x- and y-coordinates of this box need to be 0 for this function to - * work correctly. */ - struct wlr_box output_box = {0}; - wlr_output_effective_resolution(m->wlr_output, &output_box.width, &output_box.height); - - struct wlr_box intersection; - return wlr_box_intersection(&intersection, &output_box, surface_box); -} - -/* - * output_for_each_surface_iterator is a callback for rendering surfaces on an - * output. Called by wlr_surface_for_each_surface in rendering order. - * - * Params: - * - surface: The wlr_surface to be rendered on the output. - * - sx: The x-coordinate of the surface relative to the output. - * - sy: The y-coordinate of the surface relative to the output. - * - user_data: A pointer to user-specific data to be used in the callback. - */ -static void output_for_each_surface_iterator(struct wlr_surface *surface, int sx, int sy, void *user_data) -{ - struct surface_iterator_data *data = user_data; - - if (!wlr_surface_has_buffer(surface)) - return; - - struct wlr_box surface_box = data->render_box; - data->user_iterator(data->m, surface, &surface_box, data->user_data); -} - -static void render_texture(struct wlr_output *wlr_output, - pixman_region32_t *output_damage, struct wlr_texture *texture, - const struct wlr_box *box, float alpha) -{ - struct wlr_renderer *renderer = server.renderer; - - pixman_region32_t damage; - pixman_region32_init(&damage); - pixman_region32_union_rect(&damage, &damage, box->x, box->y, box->width, box->height); - pixman_region32_intersect(&damage, &damage, output_damage); - if (!pixman_region32_not_empty(&damage)) { - goto finish_damage; - } - - int nrects; - pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); - for (int i = 0; i < nrects; i++) { - scissor_output(wlr_output, &rects[i]); - wlr_render_texture(renderer, texture, wlr_output->transform_matrix, - box->x, box->y, alpha); - } - -finish_damage: - pixman_region32_fini(&damage); -} - -/* - * render_surface_iterator is a callback for rendering surfaces on an output. - * It sets up the proper transformations and scales, then calls the render - * function. Used by wlr_output_render_software_with_damage. - */ -static void render_surface_iterator(struct monitor *m, struct wlr_surface *surface, - struct wlr_box *box, void *data) -{ - struct render_texture_data *render_data = data; - float alpha = render_data->alpha; - pixman_region32_t *output_damage = render_data->output_damage; - - struct wlr_texture *texture = wlr_surface_get_texture(surface); - struct wlr_output *wlr_output = m->wlr_output; - - if (!texture) - return; - - scale_box(box, wlr_output->scale); - - /* The client has a position in layout coordinates. If you have two displays, - * one next to the other, both 1080p, a client on the rightmost display might - * have layout coordinates of 2000,100. We need to translate that to - * output-local coordinates, or (2000 - 1920). */ - double ox = box->x; - double oy = box->y; - wlr_output_layout_output_coords(server.output_layout, wlr_output, &ox, &oy); - - struct wlr_box obox = { - /* We also have to apply the scale factor for HiDPI outputs. This is only - * part of the puzzle, dwl does not fully support HiDPI. */ - .x = ox, - .y = oy, - .width = box->width, - .height = box->height - }; - - render_texture(wlr_output, output_damage, texture, &obox, alpha); - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - wlr_surface_send_frame_done(surface, &now); -} - -static void render_surface_iterator_tmp(struct monitor *m, struct wlr_surface *surface, - struct wlr_box *box, void *data) -{ - render_surface_iterator(m, surface, box, data); -} - -static void -damage_surface_iterator(struct monitor *m, struct wlr_surface *surface, - struct wlr_box *box, void *user_data) -{ - // struct wlr_output *wlr_output = m->wlr_output; - // bool whole = *(bool *) user_data; - // struct wlr_box geom = *box; - // - // scale_box(&geom, wlr_output->scale); - // - // if (whole) { - // wlr_output_damage_add_box(m->damage, &geom); - // } else if (pixman_region32_not_empty(&surface->buffer_damage)) { - // pixman_region32_t damage; - // pixman_region32_init(&damage); - // wlr_surface_get_effective_damage(surface, &damage); - // - // wlr_region_scale(&damage, &damage, wlr_output->scale); - // if (ceil(wlr_output->scale) > surface->current.scale) { - // /* When scaling up a surface it'll become - // blurry, so we need to expand the damage - // region. */ - // wlr_region_expand(&damage, &damage, ceil(wlr_output->scale) - surface->current.scale); - // } - // pixman_region32_translate(&damage, geom.x, geom.y); - // // wlr_output_damage_add(m->damage, &damage); - // pixman_region32_fini(&damage); - // } -} - -void output_damage_surface(struct monitor *m, struct wlr_surface *surface, struct wlr_box *geom, bool whole) -{ - assert(m != NULL); - if (!m->wlr_output->enabled) - return; - - double ox = geom->x, oy = geom->y; - wlr_output_layout_output_coords(server.output_layout, m->wlr_output, &ox, &oy); - - struct surface_iterator_data data = { - .user_iterator = damage_surface_iterator, - .user_data = &whole, - .m = m, - .render_box = { - .x = ox, - .y = oy, - .width = geom->width, - .height = geom->height, - }, - }; - - wlr_surface_for_each_surface(surface, output_for_each_surface_iterator, &data); -} - -static void scissor_output(struct wlr_output *output, pixman_box32_t *rect) -{ - struct wlr_renderer *renderer = server.renderer; - - struct wlr_box box = { - .x = rect->x1, - .y = rect->y1, - .width = rect->x2 - rect->x1, - .height = rect->y2 - rect->y1, - }; - - int output_width, output_height; - wlr_output_transformed_resolution(output, &output_width, &output_height); - enum wl_output_transform transform = wlr_output_transform_invert(output->transform); - wlr_box_transform(&box, &box, transform, output_width, output_height); - - wlr_renderer_scissor(renderer, &box); -} - -// TODO refactor the name it doesn't represent what this does perfectly -// returns the newly accquired hidden edges -static enum wlr_edges container_update_hidden_edges(struct container *con, struct wlr_box *borders, enum wlr_edges hidden_edges) -{ - struct monitor *m = container_get_monitor(con); - - enum wlr_edges containers_hidden_edges = WLR_EDGE_NONE; - struct wlr_box con_geom = container_get_current_geom(con); - // int border_width = container_get_border_width(con); - // hide edges if needed - if (hidden_edges & WLR_EDGE_LEFT) { - if (con_geom.x == m->root->geom.x) { - containers_hidden_edges |= WLR_EDGE_LEFT; - } - } - if (hidden_edges & WLR_EDGE_RIGHT) { - if (is_approx_equal(con_geom.x + con_geom.width, m->root->geom.x + m->root->geom.width, 3)) { - containers_hidden_edges |= WLR_EDGE_RIGHT; - } - } - if (hidden_edges & WLR_EDGE_TOP) { - if (con_geom.y == m->root->geom.y) { - containers_hidden_edges |= WLR_EDGE_TOP; - } - } - if (hidden_edges & WLR_EDGE_BOTTOM) { - if (is_approx_equal(con_geom.y + con_geom.height, m->root->geom.y + m->root->geom.height, 3)) { - containers_hidden_edges |= WLR_EDGE_BOTTOM; - } - } - - container_set_hidden_edges(con, containers_hidden_edges); - return containers_hidden_edges; -} - -static void render_borders(struct container *con, struct monitor *m, pixman_region32_t *output_damage) -{ - // TODO: reimplement me - if (!con->has_border) - return; - - struct wlr_box *borders = (struct wlr_box[4]) { - container_get_current_border_geom(con, WLR_EDGE_TOP), - container_get_current_border_geom(con, WLR_EDGE_BOTTOM), - container_get_current_border_geom(con, WLR_EDGE_LEFT), - container_get_current_border_geom(con, WLR_EDGE_RIGHT), - }; - - enum wlr_edges hidden_edges = WLR_EDGE_NONE; - struct tag *tag = monitor_get_active_tag(m); - struct layout *lt = tag_get_layout(tag); - if (lt->options->smart_hidden_edges) { - if (tag->visible_con_set->tiled_containers->len <= 1) { - hidden_edges = container_update_hidden_edges(con, borders, lt->options->hidden_edges); - } - } else { - hidden_edges = container_update_hidden_edges(con, borders, lt->options->hidden_edges); - } - - /* Draw window borders */ - struct container *sel = monitor_get_focused_container(m); - const struct color color = (con == sel) ? lt->options->focus_color : lt->options->border_color; - for (int i = 0; i < 4; i++) { - if ((hidden_edges & (1 << i)) == 0) { - struct wlr_box border = borders[i]; - double ox = border.x; - double oy = border.y; - wlr_output_layout_output_coords(server.output_layout, m->wlr_output, &ox, &oy); - struct wlr_box obox = { - .x = ox, - .y = oy, - .width = border.width, - .height = border.height, - }; - scale_box(&obox, m->wlr_output->scale); - render_rect(m, output_damage, &obox, color); - } - } -} - -void output_surface_for_each_surface(struct monitor *m, - struct wlr_surface *surface, struct wlr_box obox, - surface_iterator_func_t iterator, void *user_data) { - - struct surface_iterator_data data = { - .user_iterator = iterator, - .user_data = user_data, - .m = m, - .render_box = obox, - }; - - wlr_surface_for_each_surface(surface, - output_for_each_surface_iterator, &data); -} - -static void send_frame_done_func(struct wlr_surface *surface, - int sx, int sy, void *data) -{ - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - wlr_surface_send_frame_done(surface, &now); -} - -static void render_stack(struct monitor *m, pixman_region32_t *output_damage) -{ - /* Each subsequent window we render is rendered on top of the last. Because - * our stacking list is ordered front-to-back, we iterate over it backwards. */ - struct tag *tag = monitor_get_active_tag(m); - GPtrArray *stack_list = tag_get_complete_stack_copy(tag); - for (int i = stack_list->len-1; i >= 0; i--) { - struct container *con = g_ptr_array_index(stack_list, i); - if (!container_viewable_on_monitor(m, con)) - continue; - - render_borders(con, m, output_damage); - - /* This calls our render function for each surface among the - * xdg_surface's toplevel and popups. */ - - struct wlr_surface *surface = get_wlrsurface(con->client); - struct wlr_box obox = container_get_current_content_geom(con); - - struct render_texture_data render_data; - render_data.alpha = con->alpha; - render_data.output_damage = output_damage; - output_surface_for_each_surface(m, surface, obox, - render_surface_iterator, &render_data); - } - g_ptr_array_unref(stack_list); -} - -static void render_popups(struct monitor *m, pixman_region32_t *output_damage) -{ - for (int i = 0; i < server.popups->len; i++) { - struct xdg_popup *popup = g_ptr_array_index(server.popups, i); - struct wlr_surface *surface = popup->xdg->base->surface; - - // FIXME: popups are weird and require to use the dimensions of the - // surface instead - popup_set_width(popup, surface->current.width); - popup_set_height(popup, surface->current.height); - - struct wlr_box obox = popup->geom; - - struct render_texture_data render_data; - render_data.alpha = 1.0f; - render_data.output_damage = output_damage; - output_surface_for_each_surface(m, surface, obox, - render_surface_iterator, &render_data); - - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - wlr_surface_send_frame_done(surface, &now); - } -} - -static void clear_frame( - struct monitor *m, - struct color color, - pixman_region32_t *damage) -{ - struct wlr_renderer *renderer = server.renderer; - - /* // debug stuff */ - /* float color2[4] = {0.4f, 0.1f, 0.0f, 1.0f}; */ - /* wlr_renderer_clear(renderer, color2); */ - - float wlr_color[4]; - color_to_wlr_color(wlr_color, color); - int nrects; - pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects); - for (int i = 0; i < nrects; i++) { - scissor_output(m->wlr_output, &rects[i]); - wlr_renderer_clear(renderer, wlr_color); - } -} - -void render_monitor(struct monitor *m, pixman_region32_t *damage) -{ - /* Begin the renderer (calls glViewport and some other GL sanity checks) */ - wlr_renderer_begin(server.renderer, m->wlr_output->width, m->wlr_output->height); - - clear_frame(m, m->root->color, damage); - render_stack(m, damage); - render_popups(m, damage); - - /* Hardware cursors are rendered by the GPU on a separate plane, and can be - * moved around without re-rendering what's beneath them - which is more - * efficient. However, not all hardware supports hardware cursors. For this - * reason, wlroots provides a software fallback, which we ask it to render - * here. wlr_cursor handles configuring hardware vs software cursors for you, - * and this function is a no-op when hardware cursors are in use. */ - struct wlr_renderer *renderer = server.renderer; - wlr_renderer_scissor(renderer, NULL); - wlr_output_render_software_cursors(m->wlr_output, damage); - - /* Conclude rendering and swap the buffers, showing the final frame - * on-screen. */ - wlr_renderer_end(renderer); - - wlr_output_commit(m->wlr_output); -} - -void scale_box(struct wlr_box *box, float scale) -{ - box->x *= scale; - box->y *= scale; - box->width *= scale; - box->height *= scale; -} diff --git a/src/server.c b/src/server.c index aa1415fb..48daa84b 100644 --- a/src/server.c +++ b/src/server.c @@ -36,7 +36,6 @@ #include "xdg_shell.h" #include "translationLayer.h" #include "ipc-server.h" -#include "render/render.h" #include "keybinding.h" #include "ring_buffer.h" From 40f984e9fd2cad557d38e15f6926cb8aff7e3b6d Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 05:20:38 +0200 Subject: [PATCH 11/37] improve wlr scene implementation --- include/client.h | 4 -- include/container.h | 5 +-- src/client.c | 7 ---- src/container.c | 88 +++----------------------------------------- src/layer_shell.c | 3 -- src/meson.build | 1 - src/scratchpad.c | 1 - src/server.c | 36 ++++++++++-------- src/subsurface.c | 2 - src/tile/tileUtils.c | 5 +-- src/xdg_shell.c | 1 - src/xwayland.c | 2 - 12 files changed, 28 insertions(+), 127 deletions(-) diff --git a/include/client.h b/include/client.h index 60d76361..fb1b0ab1 100644 --- a/include/client.h +++ b/include/client.h @@ -44,10 +44,6 @@ struct client { // enum zwlr_layer_surface_v1_layer layer; int layer; - // used to determine what to damage - bool resized; - bool moved_tag; - bool is_independent; // this is currently only used for layer_shell surfaces to help determine if // arrange_layers should be called bool mapped; diff --git a/include/container.h b/include/container.h index 008b391e..720d42e0 100644 --- a/include/container.h +++ b/include/container.h @@ -86,10 +86,6 @@ void ack_configure(struct wl_listener *listener, void *data); void apply_bounds(struct wlr_box *geom, struct wlr_box box); void commit_notify(struct wl_listener *listener, void *data); void configure_notify(struct wl_listener *listener, void *data); -void container_damage_borders_at_monitor(struct container *con, struct monitor *m); -void container_damage_borders(struct container *con); -void container_damage_part(struct container *con); -void container_damage_whole(struct container *con); void container_fix_position_to_begin(struct container *con); void container_fix_position(struct container *con); void focus_on_hidden_stack(struct monitor *m, int i); @@ -107,6 +103,7 @@ void set_container_monitor(struct container *con, struct monitor *m); void resize_container(struct container *con, struct wlr_cursor *cursor, int dx, int dy); void resize_container_in_layout(struct container *con, struct wlr_box geom); void move_container(struct container *con, struct wlr_cursor *cursor, int offsetx, int offsety); +void scale_box(struct wlr_box *box, float scale); struct container_property *container_get_property(struct container *con); struct container_property *container_get_property_at_tag( diff --git a/src/client.c b/src/client.c index 7bc12997..51f51a83 100644 --- a/src/client.c +++ b/src/client.c @@ -131,8 +131,6 @@ void focus_client(struct seat *seat, struct client *old, struct client *c) if (old_surface != new_surface) { cursor_constrain(seat->cursor, NULL); unfocus_client(old); - struct container *old_con = old->con; - container_damage_borders(old_con); } } @@ -152,10 +150,6 @@ void focus_client(struct seat *seat, struct client *old, struct client *c) /* Update wlroots'c keyboard focus */ focus_surface(seat, get_wlrsurface(c)); - struct container *con = c->con; - struct monitor *m = container_get_monitor(con); - container_damage_borders_at_monitor(con, m); - /* Activate the new client */ switch (c->type) { case XDG_SHELL: @@ -282,6 +276,5 @@ void reset_floating_client_borders(int border_px) continue; } container_set_border_width(con, direction_value_uniform(border_px)); - container_damage_whole(con); } } diff --git a/src/container.c b/src/container.c index 63cb1b46..ff997c11 100644 --- a/src/container.c +++ b/src/container.c @@ -97,8 +97,6 @@ void container_property_set_floating(struct container_property *property, bool f } lift_container(con); - con->client->resized = true; - container_damage_whole(con); container_update_size(con); } @@ -181,81 +179,12 @@ void remove_container_from_tile(struct container *con) ipc_event_tag(); } -void container_damage_borders_at_monitor(struct container *con, struct monitor *m) +void scale_box(struct wlr_box *box, float scale) { - if (!con) - return; - if (!m) - return; - - struct wlr_box *borders; - borders = (struct wlr_box[4]) { - container_get_current_border_geom(con, WLR_EDGE_TOP), - container_get_current_border_geom(con, WLR_EDGE_LEFT), - container_get_current_border_geom(con, WLR_EDGE_RIGHT), - container_get_current_border_geom(con, WLR_EDGE_BOTTOM), - }; - - for (int i = 0; i < 4; i++) { - struct wlr_box border = borders[i]; - double ox = border.x; - double oy = border.y; - wlr_output_layout_output_coords(server.output_layout, m->wlr_output, &ox, &oy); - struct wlr_box obox = { - .x = ox, - .y = oy, - .width = border.width, - .height = border.height, - }; - scale_box(&obox, m->wlr_output->scale); - // wlr_output_damage_add_box(m->damage, &obox); - } -} - -void container_damage_borders(struct container *con) -{ - if (!con) - return; - - for (int i = 0; i < server.mons->len; i++) { - struct monitor *m = g_ptr_array_index(server.mons, i); - container_damage_borders_at_monitor(con, m); - } -} - -static void damage_container_area(struct container *con, struct wlr_box geom, - bool whole) -{ - for (int i = 0; i < server.mons->len; i++) { - struct monitor *m = g_ptr_array_index(server.mons, i); - output_damage_surface(m, get_wlrsurface(con->client), &geom, whole); - } - container_damage_borders(con); -} - -static void container_damage(struct container *con, bool whole) -{ - for (int i = 0; i < server.mons->len; i++) { - struct wlr_box con_geom = container_get_current_content_geom(con); - damage_container_area(con, con_geom, whole); - } - - struct client *c = con->client; - if (c->resized || c->moved_tag) { - damage_container_area(con, con->prev_geom, whole); - c->resized = false; - c->moved_tag = false; - } -} - -void container_damage_part(struct container *con) -{ - container_damage(con, false); -} - -void container_damage_whole(struct container *con) -{ - container_damage(con, true); + box->x *= scale; + box->y *= scale; + box->width *= scale; + box->height *= scale; } struct container *monitor_get_focused_container(struct monitor *m) @@ -426,7 +355,6 @@ void commit_notify(struct wl_listener *listener, void *data) struct container *con = c->con; if (con->is_on_tile) { - container_damage_part(c->con); } } @@ -763,9 +691,6 @@ void move_container(struct container *con, struct wlr_cursor *cursor, int offset struct tag *tag = monitor_get_active_tag(m); struct layout *lt = tag_get_layout(tag); container_set_border_width(con, direction_value_uniform(lt->options->float_border_px)); - - con->client->resized = true; - container_damage(con, true); } struct container_property *container_get_property(struct container *con) @@ -1174,7 +1099,6 @@ void resize_container(struct container *con, struct wlr_cursor *cursor, int offs arrange(); } - container_damage_borders(con); container_set_floating_geom(con, geom); struct tag *tag = container_get_current_tag(con); @@ -1404,8 +1328,6 @@ void move_container_to_tag(struct container *con, struct tag *tag) return; container_set_tag(con, tag); - con->client->moved_tag = true; - container_damage_whole(con); struct tag *old_tag = container_get_current_tag(con); diff --git a/src/layer_shell.c b/src/layer_shell.c index 846b56b5..217bc41f 100644 --- a/src/layer_shell.c +++ b/src/layer_shell.c @@ -66,7 +66,6 @@ void unmap_layer_surface_notify(struct wl_listener *listener, void *data) { struct client *c = wl_container_of(listener, c, unmap); unmap_layer_surface(c); - container_damage_whole(c->con); } void destroy_layer_surface_notify(struct wl_listener *listener, void *data) @@ -117,8 +116,6 @@ void commit_layer_surface_notify(struct wl_listener *listener, void *data) c->mapped = layer_surface->mapped; arrange_layers(c->m); } - - container_damage_part(con); } bool layer_shell_is_bar(struct container *con) diff --git a/src/meson.build b/src/meson.build index bf120c38..2035653a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -75,7 +75,6 @@ srcs = files( 'list_sets/container_stack_set.c', 'list_sets/focus_stack_set.c', 'list_sets/list_set.c', - 'render/render.c', 'rules/mon_rule.c', 'rules/rule.c', 'tile/tileUtils.c', diff --git a/src/scratchpad.c b/src/scratchpad.c index 246ae269..7888acf4 100644 --- a/src/scratchpad.c +++ b/src/scratchpad.c @@ -34,7 +34,6 @@ void move_to_scratchpad(struct container *con, int position) struct tag *tag = monitor_get_active_tag(m); tagset_reload(tag); - container_damage_whole(con); arrange(); tag_focus_most_recent_container(tag); } diff --git a/src/server.c b/src/server.c index 48daa84b..951dd37e 100644 --- a/src/server.c +++ b/src/server.c @@ -402,31 +402,35 @@ static void _async_handler_function(struct uv_async_s *arg) } static void surface_handle_commit(struct wl_listener *listener, void *data) { - struct scene_surface *surface = wl_container_of(listener, surface, commit); + struct scene_surface *surface = wl_container_of(listener, surface, commit); } static void surface_handle_destroy(struct wl_listener *listener, void *data) { - struct scene_surface *surface = wl_container_of(listener, surface, destroy); - wlr_scene_node_destroy(&surface->scene_surface->buffer->node); - wlr_scene_node_destroy(&surface->border->node); - wl_list_remove(&surface->destroy.link); - free(surface); + struct scene_surface *surface = wl_container_of(listener, surface, destroy); + wlr_scene_node_destroy(&surface->scene_surface->buffer->node); + wlr_scene_node_destroy(&surface->border->node); + wl_list_remove(&surface->destroy.link); + free(surface); } static void server_handle_new_surface(struct wl_listener *listener, void *data) { - struct server *server = wl_container_of(listener, server, new_surface); - struct wlr_surface *wlr_surface = data; + struct server *server = wl_container_of(listener, server, new_surface); + struct wlr_surface *wlr_surface = data; - struct scene_surface *surface = calloc(1, sizeof(struct scene_surface)); - surface->wlr = wlr_surface; - surface->commit.notify = surface_handle_commit; - wl_signal_add(&wlr_surface->events.commit, &surface->commit); - surface->destroy.notify = surface_handle_destroy; - wl_signal_add(&wlr_surface->events.destroy, &surface->destroy); + struct scene_surface *surface = calloc(1, sizeof(struct scene_surface)); + surface->wlr = wlr_surface; + surface->commit.notify = surface_handle_commit; + wl_signal_add(&wlr_surface->events.commit, &surface->commit); + surface->destroy.notify = surface_handle_destroy; + wl_signal_add(&wlr_surface->events.destroy, &surface->destroy); - surface->scene_surface = - wlr_scene_surface_create(&server->scene->tree, wlr_surface); + surface->scene_surface = + wlr_scene_surface_create(&server->scene->tree, wlr_surface); + + wlr_surface->data = surface; + + wlr_scene_node_set_position(&surface->scene_surface->buffer->node, 300, 300); } int setup_server(struct server *server) diff --git a/src/subsurface.c b/src/subsurface.c index f407c2c8..da66a4d2 100644 --- a/src/subsurface.c +++ b/src/subsurface.c @@ -22,13 +22,11 @@ static void handle_subsurface_commit(struct wl_listener *listener, void *data) // TODO: We should damage the subsurface directly and render the damage // directly instead of leaving this job to the parent surface. This should // save us cpu cycles - container_damage_part(xdg_subsurface->parent); } static void handle_subsurface_destroy(struct wl_listener *listener, void *data) { struct subsurface *subsurface = wl_container_of(listener, subsurface, destroy); - container_damage_whole(subsurface->parent); destroy_subsurface(subsurface); } diff --git a/src/tile/tileUtils.c b/src/tile/tileUtils.c index 9a04d3e5..c006fef1 100644 --- a/src/tile/tileUtils.c +++ b/src/tile/tileUtils.c @@ -238,7 +238,6 @@ void arrange_monitor(struct monitor *m) arrange_containers(tag, active_geom, tiled_containers); g_ptr_array_unref(tiled_containers); - // wlr_output_damage_add_whole(m->damage); update_reduced_focus_stack(tag); tag_focus_most_recent_container(tag); } @@ -296,8 +295,6 @@ static void arrange_container(struct container *con, struct monitor *m, void container_update_size(struct container *con) { - con->client->resized = true; - struct wlr_box con_geom = container_get_current_geom(con); if (!container_is_tiled(con)) { @@ -307,6 +304,8 @@ void container_update_size(struct container *con) container_set_current_geom(con, con_geom); } + struct scene_surface *surface = get_wlrsurface(con->client)->data; + wlr_scene_node_set_position(&surface->scene_surface->buffer->node, con_geom.x, con_geom.y); /* wlroots makes this a no-op if size hasn't changed */ switch (con->client->type) { case XDG_SHELL: diff --git a/src/xdg_shell.c b/src/xdg_shell.c index b6ebbbdf..83f8bffa 100644 --- a/src/xdg_shell.c +++ b/src/xdg_shell.c @@ -110,7 +110,6 @@ void unmap_notify(struct wl_listener *listener, void *data) struct client *c = wl_container_of(listener, c, unmap); struct container *con = c->con; - container_damage_whole(c->con); remove_container_from_tile(con); arrange(); diff --git a/src/xwayland.c b/src/xwayland.c index b060a450..acfaad9f 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -129,7 +129,6 @@ void unmap_notifyx11(struct wl_listener *listener, void *data) wl_list_remove(&c->commit.link); struct container *con = c->con; - container_damage_whole(c->con); remove_container_from_tile(con); arrange(); @@ -195,7 +194,6 @@ void maprequestx11(struct wl_listener *listener, void *data) case X11_UNMANAGED: { con->is_unmanaged = true; - c->is_independent = true; debug_print("is unmanaged\n"); struct tag *tag = monitor_get_active_tag(m); From bd9c25bf64768be944632593ee5d2f5328ee955b Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 10:52:13 +0200 Subject: [PATCH 12/37] fix stuff --- include/server.h | 3 + src/server.c | 987 +++++++++++++++++++++++++---------------------- src/xdg_shell.c | 1 + src/xwayland.c | 2 +- 4 files changed, 523 insertions(+), 470 deletions(-) diff --git a/include/server.h b/include/server.h index a00c69c2..10e2f4ef 100644 --- a/include/server.h +++ b/include/server.h @@ -189,4 +189,7 @@ BitSet *server_bitset_get_local_tmp_copy(BitSet *bitset); struct tag *server_get_selected_tag(); struct layout *server_get_selected_layout(); + +struct client *wlr_surface_get_client(struct wlr_surface *wlr_surface); +struct container *wlr_surface_get_container(struct wlr_surface *wlr_surface); #endif /* SERVER_H */ diff --git a/src/server.c b/src/server.c index 951dd37e..9eb595d8 100644 --- a/src/server.c +++ b/src/server.c @@ -2,9 +2,9 @@ #include "list_sets/container_stack_set.h" #include "list_sets/focus_stack_set.h" -#include "tag.h" #include "monitor.h" #include "stringop.h" +#include "tag.h" #include #include @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include #include @@ -24,20 +26,17 @@ #include #include #include -#include #include -#include -#include +#include "ipc-server.h" +#include "keybinding.h" #include "layer_shell.h" #include "monitor.h" +#include "ring_buffer.h" +#include "translationLayer.h" #include "utils/coreUtils.h" #include "utils/parseConfigUtils.h" #include "xdg_shell.h" -#include "translationLayer.h" -#include "ipc-server.h" -#include "keybinding.h" -#include "ring_buffer.h" #define XDG_SHELL_VERSION 2 @@ -55,357 +54,421 @@ static void finalize_lua_api(struct server *server); static struct tag *handle_too_few_tags(uint32_t tag_id); -static struct tag *handle_too_few_tags(uint32_t tag_id) -{ - // no number has more than 11 digits when int is 32 bit long - char name[12]; - // TODO explain why +1 - snprintf(name, 12, "%d:%d", tag_id, c_idx_to_lua_idx(tag_id)); - - struct tag *new_tag = create_tag(name, tag_id, server.default_layout); - int *tag_id_ptr = malloc(sizeof(*tag_id_ptr)); - *tag_id_ptr = tag_id; - g_hash_table_insert(server.tags, tag_id_ptr, new_tag); - struct tag *tag = get_tag(0); - wlr_list_cat(new_tag->con_set->tiled_containers, tag->con_set->tiled_containers); - - wlr_list_cat(new_tag->focus_set->focus_stack_layer_background, tag->focus_set->focus_stack_layer_background); - wlr_list_cat(new_tag->focus_set->focus_stack_layer_bottom, tag->focus_set->focus_stack_layer_bottom); - wlr_list_cat(new_tag->focus_set->focus_stack_layer_top, tag->focus_set->focus_stack_layer_top); - wlr_list_cat(new_tag->focus_set->focus_stack_layer_overlay, tag->focus_set->focus_stack_layer_overlay); - wlr_list_cat(new_tag->focus_set->focus_stack_on_top, tag->focus_set->focus_stack_on_top); - wlr_list_cat(new_tag->focus_set->focus_stack_normal, tag->focus_set->focus_stack_normal); - wlr_list_cat(new_tag->focus_set->focus_stack_not_focusable, tag->focus_set->focus_stack_not_focusable); - - wlr_list_cat(new_tag->visible_con_set->tiled_containers, tag->visible_con_set->tiled_containers); - - wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_background, tag->visible_focus_set->focus_stack_layer_background); - wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_bottom, tag->visible_focus_set->focus_stack_layer_bottom); - wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_top, tag->visible_focus_set->focus_stack_layer_top); - wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_overlay, tag->visible_focus_set->focus_stack_layer_overlay); - wlr_list_cat(new_tag->visible_focus_set->focus_stack_on_top, tag->visible_focus_set->focus_stack_on_top); - wlr_list_cat(new_tag->visible_focus_set->focus_stack_normal, tag->visible_focus_set->focus_stack_normal); - wlr_list_cat(new_tag->visible_focus_set->focus_stack_not_focusable, tag->visible_focus_set->focus_stack_not_focusable); - - return new_tag; +static struct tag *handle_too_few_tags(uint32_t tag_id) { + // no number has more than 11 digits when int is 32 bit long + char name[12]; + // TODO explain why +1 + snprintf(name, 12, "%d:%d", tag_id, c_idx_to_lua_idx(tag_id)); + + struct tag *new_tag = create_tag(name, tag_id, server.default_layout); + int *tag_id_ptr = malloc(sizeof(*tag_id_ptr)); + *tag_id_ptr = tag_id; + g_hash_table_insert(server.tags, tag_id_ptr, new_tag); + struct tag *tag = get_tag(0); + wlr_list_cat(new_tag->con_set->tiled_containers, + tag->con_set->tiled_containers); + + wlr_list_cat(new_tag->focus_set->focus_stack_layer_background, + tag->focus_set->focus_stack_layer_background); + wlr_list_cat(new_tag->focus_set->focus_stack_layer_bottom, + tag->focus_set->focus_stack_layer_bottom); + wlr_list_cat(new_tag->focus_set->focus_stack_layer_top, + tag->focus_set->focus_stack_layer_top); + wlr_list_cat(new_tag->focus_set->focus_stack_layer_overlay, + tag->focus_set->focus_stack_layer_overlay); + wlr_list_cat(new_tag->focus_set->focus_stack_on_top, + tag->focus_set->focus_stack_on_top); + wlr_list_cat(new_tag->focus_set->focus_stack_normal, + tag->focus_set->focus_stack_normal); + wlr_list_cat(new_tag->focus_set->focus_stack_not_focusable, + tag->focus_set->focus_stack_not_focusable); + + wlr_list_cat(new_tag->visible_con_set->tiled_containers, + tag->visible_con_set->tiled_containers); + + wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_background, + tag->visible_focus_set->focus_stack_layer_background); + wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_bottom, + tag->visible_focus_set->focus_stack_layer_bottom); + wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_top, + tag->visible_focus_set->focus_stack_layer_top); + wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_overlay, + tag->visible_focus_set->focus_stack_layer_overlay); + wlr_list_cat(new_tag->visible_focus_set->focus_stack_on_top, + tag->visible_focus_set->focus_stack_on_top); + wlr_list_cat(new_tag->visible_focus_set->focus_stack_normal, + tag->visible_focus_set->focus_stack_normal); + wlr_list_cat(new_tag->visible_focus_set->focus_stack_not_focusable, + tag->visible_focus_set->focus_stack_not_focusable); + + return new_tag; +} + +static void init_lists(struct server *server) { + server->layer_visual_stack_lists = g_ptr_array_new(); + + server->layer_visual_stack_background = g_ptr_array_new(); + server->layer_visual_stack_bottom = g_ptr_array_new(); + server->layer_visual_stack_top = g_ptr_array_new(); + server->layer_visual_stack_overlay = g_ptr_array_new(); + + g_ptr_array_add(server->layer_visual_stack_lists, + server->layer_visual_stack_overlay); + g_ptr_array_add(server->layer_visual_stack_lists, + server->layer_visual_stack_top); + g_ptr_array_add(server->layer_visual_stack_lists, + server->layer_visual_stack_bottom); + g_ptr_array_add(server->layer_visual_stack_lists, + server->layer_visual_stack_background); +} + +static void finalize_lists(struct server *server) { + g_ptr_array_unref(server->layer_visual_stack_background); + g_ptr_array_unref(server->layer_visual_stack_bottom); + g_ptr_array_unref(server->layer_visual_stack_top); + g_ptr_array_unref(server->layer_visual_stack_overlay); + + g_ptr_array_unref(server->layer_visual_stack_lists); } +static int clear_key_combo_timer_callback(void *data) { + GPtrArray *registered_key_combos = server.registered_key_combos; + char *bind = join_string((const char **)registered_key_combos->pdata, + registered_key_combos->len, " "); -static void init_lists(struct server *server) -{ - server->layer_visual_stack_lists = g_ptr_array_new(); + struct tag *tag = server_get_selected_tag(); + struct layout *lt = tag_get_layout(tag); - server->layer_visual_stack_background = g_ptr_array_new(); - server->layer_visual_stack_bottom = g_ptr_array_new(); - server->layer_visual_stack_top = g_ptr_array_new(); - server->layer_visual_stack_overlay = g_ptr_array_new(); + process_binding(lt, bind); + free(bind); - g_ptr_array_add(server->layer_visual_stack_lists, server->layer_visual_stack_overlay); - g_ptr_array_add(server->layer_visual_stack_lists, server->layer_visual_stack_top); - g_ptr_array_add(server->layer_visual_stack_lists, server->layer_visual_stack_bottom); - g_ptr_array_add(server->layer_visual_stack_lists, server->layer_visual_stack_background); + list_clear(server.registered_key_combos, free); + return 0; } -static void finalize_lists(struct server *server) -{ - g_ptr_array_unref(server->layer_visual_stack_background); - g_ptr_array_unref(server->layer_visual_stack_bottom); - g_ptr_array_unref(server->layer_visual_stack_top); - g_ptr_array_unref(server->layer_visual_stack_overlay); - - g_ptr_array_unref(server->layer_visual_stack_lists); +static void init_timers(struct server *server) { + server->combo_timer_source = wl_event_loop_add_timer( + server->wl_event_loop, clear_key_combo_timer_callback, + server->registered_key_combos); } -static int clear_key_combo_timer_callback(void *data) { - GPtrArray *registered_key_combos = server.registered_key_combos; - char *bind = join_string((const char **)registered_key_combos->pdata, registered_key_combos->len, " "); - - struct tag *tag = server_get_selected_tag(); - struct layout *lt = tag_get_layout(tag); - - process_binding(lt, bind); - free(bind); - - list_clear(server.registered_key_combos, free); - return 0; +static void finalize_timers(struct server *server) { + wl_event_source_remove(server->combo_timer_source); } -static void init_timers(struct server *server) -{ - server->combo_timer_source = wl_event_loop_add_timer( - server->wl_event_loop, - clear_key_combo_timer_callback, - server->registered_key_combos - ); -} +static int init_backend(struct server *server) { + /* The Wayland display is managed by libwayland. It handles accepting + * clients from the Unix socket, manging Wayland globals, and so on. */ + server->wl_display = wl_display_create(); + server->wl_event_loop = wl_display_get_event_loop(server->wl_display); -static void finalize_timers(struct server *server) -{ - wl_event_source_remove(server->combo_timer_source); -} + init_timers(server); -static int init_backend(struct server *server) -{ - /* The Wayland display is managed by libwayland. It handles accepting - * clients from the Unix socket, manging Wayland globals, and so on. */ - server->wl_display = wl_display_create(); - server->wl_event_loop = wl_display_get_event_loop(server->wl_display); - - init_timers(server); - - /* The backend is a wlroots feature which abstracts the underlying input and - * output hardware. The autocreate option will choose the most suitable - * backend based on the current environment, such as opening an X11 window - * if an X11 server is running. The NULL argument here optionally allows you - * to pass in a custom renderer if wlr_renderer doesnt). */ - if (!(server->backend = wlr_backend_autocreate(server->wl_display))) { - printf("couldn't create backend\n"); - return EXIT_FAILURE; - } - return EXIT_SUCCESS; + /* The backend is a wlroots feature which abstracts the underlying input and + * output hardware. The autocreate option will choose the most suitable + * backend based on the current environment, such as opening an X11 window + * if an X11 server is running. The NULL argument here optionally allows you + * to pass in a custom renderer if wlr_renderer doesnt). */ + if (!(server->backend = wlr_backend_autocreate(server->wl_display))) { + printf("couldn't create backend\n"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } -static void init_event_handlers(struct server *server) -{ - LISTEN(&server->backend->events.new_output, &server->new_output, create_monitor); - /* Use xdg_decoration protocol to negotiate server-side decorations */ - server->xdeco_mgr = wlr_xdg_decoration_manager_v1_create(server->wl_display); - LISTEN(&server->xdeco_mgr->events.new_toplevel_decoration, &server->new_xdeco, createxdeco); +static void init_event_handlers(struct server *server) { + LISTEN(&server->backend->events.new_output, &server->new_output, + create_monitor); + /* Use xdg_decoration protocol to negotiate server-side decorations */ + server->xdeco_mgr = wlr_xdg_decoration_manager_v1_create(server->wl_display); + LISTEN(&server->xdeco_mgr->events.new_toplevel_decoration, &server->new_xdeco, + createxdeco); - server->xdg_shell = wlr_xdg_shell_create(server->wl_display, XDG_SHELL_VERSION); - // remove csd(client side decorations) completely from xdg based windows - wlr_server_decoration_manager_set_default_mode( - wlr_server_decoration_manager_create(server->wl_display), - WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); - LISTEN(&server->xdg_shell->events.new_surface, &server->new_xdg_surface, create_notify_xdg); + server->xdg_shell = + wlr_xdg_shell_create(server->wl_display, XDG_SHELL_VERSION); + // remove csd(client side decorations) completely from xdg based windows + wlr_server_decoration_manager_set_default_mode( + wlr_server_decoration_manager_create(server->wl_display), + WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); + LISTEN(&server->xdg_shell->events.new_surface, &server->new_xdg_surface, + create_notify_xdg); - server->layer_shell = wlr_layer_shell_v1_create(server->wl_display); - LISTEN(&server->layer_shell->events.new_surface, &server->new_layer_shell_surface, create_notify_layer_shell); + server->layer_shell = wlr_layer_shell_v1_create(server->wl_display); + LISTEN(&server->layer_shell->events.new_surface, + &server->new_layer_shell_surface, create_notify_layer_shell); - server->pointer_constraints = wlr_pointer_constraints_v1_create(server->wl_display); - LISTEN(&server->pointer_constraints->events.new_constraint, &server->new_pointer_constraint, handle_new_pointer_constraint); + server->pointer_constraints = + wlr_pointer_constraints_v1_create(server->wl_display); + LISTEN(&server->pointer_constraints->events.new_constraint, + &server->new_pointer_constraint, handle_new_pointer_constraint); - server->output_mgr = wlr_output_manager_v1_create(server->wl_display); - LISTEN(&server->output_mgr->events.apply, &server->output_mgr_apply, handle_output_mgr_apply); - LISTEN(&server->output_mgr->events.test, &server->output_mgr_test, handle_output_mgr_test); + server->output_mgr = wlr_output_manager_v1_create(server->wl_display); + LISTEN(&server->output_mgr->events.apply, &server->output_mgr_apply, + handle_output_mgr_apply); + LISTEN(&server->output_mgr->events.test, &server->output_mgr_test, + handle_output_mgr_test); - server->tablet_mgr = wlr_tablet_v2_create(server->wl_display); + server->tablet_mgr = wlr_tablet_v2_create(server->wl_display); } -static void finalize_event_handlers(struct server *server) -{ - destroy_event_handler(server->event_handler); +static void finalize_event_handlers(struct server *server) { + destroy_event_handler(server->event_handler); } -void init_server() -{ - server = (struct server) { - }; +void init_server() { + server = (struct server){}; - server.registered_key_combos = g_ptr_array_new(); - server.named_key_combos = g_ptr_array_new(); - server.error_path = strdup("$HOME/.config/japokwm"); - expand_path(&server.error_path); + server.registered_key_combos = g_ptr_array_new(); + server.named_key_combos = g_ptr_array_new(); + server.error_path = strdup("$HOME/.config/japokwm"); + expand_path(&server.error_path); - init_lists(&server); + init_lists(&server); - server.mons = g_ptr_array_new(); - server.popups = g_ptr_array_new(); - server.xwayland_popups = g_ptr_array_new(); + server.mons = g_ptr_array_new(); + server.popups = g_ptr_array_new(); + server.xwayland_popups = g_ptr_array_new(); - server.scratchpad = g_ptr_array_new(); - server.keyboards = g_ptr_array_new(); - server.config_paths = create_default_config_paths(); - server.user_data_paths = create_default_user_data_paths(); - server.layout_paths = create_default_layout_paths(); - server.tags = create_tags(); + server.scratchpad = g_ptr_array_new(); + server.keyboards = g_ptr_array_new(); + server.config_paths = create_default_config_paths(); + server.user_data_paths = create_default_user_data_paths(); + server.layout_paths = create_default_layout_paths(); + server.tags = create_tags(); - server.container_stack = g_ptr_array_new(); + server.container_stack = g_ptr_array_new(); - server.event_handler = create_event_handler(); + server.event_handler = create_event_handler(); - server.previous_tag = 0; - server.previous_bitset = bitset_create(); + server.previous_tag = 0; + server.previous_bitset = bitset_create(); - server_prohibit_reloading_config(); + server_prohibit_reloading_config(); - init_lua_api(&server); - init_error_file(); + init_lua_api(&server); + init_error_file(); - server.default_layout_ring = create_ring_buffer(); - server_reset_layout_ring(server.default_layout_ring); + server.default_layout_ring = create_ring_buffer(); + server_reset_layout_ring(server.default_layout_ring); - server.default_layout = create_layout(L); + server.default_layout = create_layout(L); - load_lua_api(L); - if (init_backend(&server) != EXIT_SUCCESS) { - return; - } + load_lua_api(L); + if (init_backend(&server) != EXIT_SUCCESS) { + return; + } - ipc_init(server.wl_event_loop); + ipc_init(server.wl_event_loop); - /* Creates an output layout, which a wlroots utility for working with an - * arrangement of screens in a physical layout. */ - server.output_layout = wlr_output_layout_create(); + /* Creates an output layout, which a wlroots utility for working with an + * arrangement of screens in a physical layout. */ + server.output_layout = wlr_output_layout_create(); } -void finalize_server() -{ - g_ptr_array_unref(server.registered_key_combos); - g_ptr_array_unref(server.named_key_combos); +void finalize_server() { + g_ptr_array_unref(server.registered_key_combos); + g_ptr_array_unref(server.named_key_combos); - finalize_lists(&server); - finalize_event_handlers(&server); + finalize_lists(&server); + finalize_event_handlers(&server); - bitset_destroy(server.previous_bitset); + bitset_destroy(server.previous_bitset); - // NOTE: these bitsets are created lazily, so they may be NULL but that is - // ok since bitset_destroy handles this case. - bitset_destroy(server.tmp_bitset); - bitset_destroy(server.local_tmp_bitset); + // NOTE: these bitsets are created lazily, so they may be NULL but that is + // ok since bitset_destroy handles this case. + bitset_destroy(server.tmp_bitset); + bitset_destroy(server.local_tmp_bitset); - g_ptr_array_unref(server.mons); - g_ptr_array_unref(server.popups); - g_ptr_array_unref(server.xwayland_popups); + g_ptr_array_unref(server.mons); + g_ptr_array_unref(server.popups); + g_ptr_array_unref(server.xwayland_popups); - g_ptr_array_unref(server.scratchpad); - g_ptr_array_unref(server.keyboards); - g_ptr_array_unref(server.config_paths); - g_ptr_array_unref(server.user_data_paths); - g_ptr_array_unref(server.layout_paths); + g_ptr_array_unref(server.scratchpad); + g_ptr_array_unref(server.keyboards); + g_ptr_array_unref(server.config_paths); + g_ptr_array_unref(server.user_data_paths); + g_ptr_array_unref(server.layout_paths); - g_ptr_array_unref(server.container_stack); + g_ptr_array_unref(server.container_stack); } -void server_terminate(struct server *server) -{ - server->is_running = false; - wl_display_terminate(server->wl_display); - uv_loop_close(server->uv_loop); +void server_terminate(struct server *server) { + server->is_running = false; + wl_display_terminate(server->wl_display); + uv_loop_close(server->uv_loop); } - static void run_event_loop() { - int pfd_size = 2; - struct pollfd pfds[pfd_size]; - - pfds[0].fd = wl_event_loop_get_fd(server.wl_event_loop); - pfds[0].events = POLLIN; - - pfds[1].fd = uv_backend_fd(server.uv_loop); - pfds[1].events = POLLIN; - - server.is_running = 1; - while (server.is_running) { - wl_display_flush_clients(server.wl_display); - - /* poll waits for any event of either the wayland event loop or the - * libuv event loop and only if one emits an event we continue */ - poll(pfds, pfd_size, -1); - - // TODO: we can probably run this more efficiently - uv_run(server.uv_loop, UV_RUN_NOWAIT); - wl_event_loop_dispatch(server.wl_event_loop, 0); - } -} - - -static void run(char *startup_cmd) -{ - pid_t startup_pid = -1; - - /* Add a Unix socket to the Wayland display. */ - const char *socket = wl_display_add_socket_auto(server.wl_display); - - if (!socket) - printf("startup: display_add_socket_auto\n"); - - /* Set the WAYLAND_DISPLAY environment variable to our socket and run the - * startup command if requested. */ - setenv("WAYLAND_DISPLAY", socket, 1); - - /* Start the backend. This will enumerate outputs and inputs, become the DRM - * master, etc */ - if (!wlr_backend_start(server.backend)) { - printf("Failed to start backend"); - wlr_backend_destroy(server.backend); - return; - } - - /* Now that outputs are initialized, choose initial selMon based on - * cursor position, and set default cursor image */ - update_monitor_geometries(); - struct seat *seat = input_manager_get_default_seat(); - struct cursor *cursor = seat->cursor; - struct monitor *m = xy_to_monitor(cursor->wlr_cursor->x, cursor->wlr_cursor->y); - focus_monitor(m); - - /* XXX hack to get cursor to display in its initial location (100, 100) - * instead of (0, 0) and then jumping. still may not be fully - * initialized, as the image/coordinates are not transformed for the - * monitor when displayed here */ - wlr_cursor_warp_closest(seat->cursor->wlr_cursor, NULL, cursor->wlr_cursor->x, cursor->wlr_cursor->y); - wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_mgr, "left_ptr", cursor->wlr_cursor); - - if (startup_cmd) { - startup_pid = fork(); - if (startup_pid == 0) { - execl("/bin/sh", "/bin/sh", "-c", startup_cmd, (void *)NULL); - } + int pfd_size = 2; + struct pollfd pfds[pfd_size]; + + pfds[0].fd = wl_event_loop_get_fd(server.wl_event_loop); + pfds[0].events = POLLIN; + + pfds[1].fd = uv_backend_fd(server.uv_loop); + pfds[1].events = POLLIN; + + server.is_running = 1; + while (server.is_running) { + wl_display_flush_clients(server.wl_display); + + /* poll waits for any event of either the wayland event loop or the + * libuv event loop and only if one emits an event we continue */ + poll(pfds, pfd_size, -1); + + // TODO: we can probably run this more efficiently + uv_run(server.uv_loop, UV_RUN_NOWAIT); + wl_event_loop_dispatch(server.wl_event_loop, 0); + } +} + +static void run(char *startup_cmd) { + pid_t startup_pid = -1; + + /* Add a Unix socket to the Wayland display. */ + const char *socket = wl_display_add_socket_auto(server.wl_display); + + if (!socket) + printf("startup: display_add_socket_auto\n"); + + /* Set the WAYLAND_DISPLAY environment variable to our socket and run the + * startup command if requested. */ + setenv("WAYLAND_DISPLAY", socket, 1); + + /* Start the backend. This will enumerate outputs and inputs, become the DRM + * master, etc */ + if (!wlr_backend_start(server.backend)) { + printf("Failed to start backend"); + wlr_backend_destroy(server.backend); + return; + } + + /* Now that outputs are initialized, choose initial selMon based on + * cursor position, and set default cursor image */ + update_monitor_geometries(); + struct seat *seat = input_manager_get_default_seat(); + struct cursor *cursor = seat->cursor; + struct monitor *m = + xy_to_monitor(cursor->wlr_cursor->x, cursor->wlr_cursor->y); + focus_monitor(m); + + /* XXX hack to get cursor to display in its initial location (100, 100) + * instead of (0, 0) and then jumping. still may not be fully + * initialized, as the image/coordinates are not transformed for the + * monitor when displayed here */ + wlr_cursor_warp_closest(seat->cursor->wlr_cursor, NULL, cursor->wlr_cursor->x, + cursor->wlr_cursor->y); + wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_mgr, "left_ptr", + cursor->wlr_cursor); + + if (startup_cmd) { + startup_pid = fork(); + if (startup_pid == 0) { + execl("/bin/sh", "/bin/sh", "-c", startup_cmd, (void *)NULL); } + } - run_event_loop(); + run_event_loop(); - if (startup_cmd) { - kill(startup_pid, SIGTERM); - waitpid(startup_pid, NULL, 0); - } + if (startup_cmd) { + kill(startup_pid, SIGTERM); + waitpid(startup_pid, NULL, 0); + } } -static void init_lua_api(struct server *server) -{ - L = luaL_newstate(); - luaL_openlibs(L); - lua_setwarnf(L, handle_warning, NULL); +static void init_lua_api(struct server *server) { + L = luaL_newstate(); + luaL_openlibs(L); + lua_setwarnf(L, handle_warning, NULL); } -static void finalize_lua_api(struct server *server) -{ - lua_close(L); -} +static void finalize_lua_api(struct server *server) { lua_close(L); } -void server_reset_layout_ring(struct ring_buffer *layout_ring) -{ - list_clear(layout_ring->names, NULL); - g_ptr_array_add(layout_ring->names, strdup("tile")); - g_ptr_array_add(layout_ring->names, strdup("monocle")); +void server_reset_layout_ring(struct ring_buffer *layout_ring) { + list_clear(layout_ring->names, NULL); + g_ptr_array_add(layout_ring->names, strdup("tile")); + g_ptr_array_add(layout_ring->names, strdup("monocle")); } -static void _async_handler_function(struct uv_async_s *arg) -{ - // struct function_data *func_data = data->data; - // printf("the end\n"); - // free(func_data->output); +static void _async_handler_function(struct uv_async_s *arg) { + // struct function_data *func_data = data->data; + // printf("the end\n"); + // free(func_data->output); - struct function_data *data = arg->data; + struct function_data *data = arg->data; - lua_State *L = data->L; - int func_ref = data->lua_func_ref; - printf("the end %d\n", func_ref); + lua_State *L = data->L; + int func_ref = data->lua_func_ref; + printf("the end %d\n", func_ref); - lua_rawgeti(L, LUA_REGISTRYINDEX, func_ref); - lua_pushstring(L, data->output); - lua_call_safe(L, 1, 0, 0); - luaL_unref(L, LUA_REGISTRYINDEX, func_ref); + lua_rawgeti(L, LUA_REGISTRYINDEX, func_ref); + lua_pushstring(L, data->output); + lua_call_safe(L, 1, 0, 0); + luaL_unref(L, LUA_REGISTRYINDEX, func_ref); - free(data); + free(data); } static void surface_handle_commit(struct wl_listener *listener, void *data) { struct scene_surface *surface = wl_container_of(listener, surface, commit); + + struct client *c = wlr_surface_get_client(surface->wlr); + struct container *con = c->con; + struct wlr_box *borders = (struct wlr_box[4]) { + container_get_current_border_geom(con, WLR_EDGE_TOP), + container_get_current_border_geom(con, WLR_EDGE_BOTTOM), + container_get_current_border_geom(con, WLR_EDGE_LEFT), + container_get_current_border_geom(con, WLR_EDGE_RIGHT), + }; + for (int i = 0; i < 4; i++) { + struct wlr_box border = borders[i]; + scale_box(&obox, m->wlr_output->scale); + } } -static void surface_handle_destroy(struct wl_listener *listener, void *data) { +// static void render_borders(struct container *con, struct monitor *m, +// pixman_region32_t *output_damage) +// { +// // TODO: reimplement me +// if (!con->has_border) +// return; +// +// enum wlr_edges hidden_edges = WLR_EDGE_NONE; +// struct tag *tag = monitor_get_active_tag(m); +// struct layout *lt = tag_get_layout(tag); +// if (lt->options->smart_hidden_edges) { +// if (tag->visible_con_set->tiled_containers->len <= 1) { +// hidden_edges = container_update_hidden_edges(con, borders, +// lt->options->hidden_edges); +// } +// } else { +// hidden_edges = container_update_hidden_edges(con, borders, +// lt->options->hidden_edges); +// } +// +// /* Draw window borders */ +// struct container *sel = monitor_get_focused_container(m); +// const struct color color = (con == sel) ? lt->options->focus_color : +// lt->options->border_color; for (int i = 0; i < 4; i++) { +// if ((hidden_edges & (1 << i)) == 0) { +// struct wlr_box border = borders[i]; +// double ox = border.x; +// double oy = border.y; +// wlr_output_layout_output_coords(server.output_layout, +// m->wlr_output, &ox, &oy); struct wlr_box obox = { +// .x = ox, +// .y = oy, +// .width = border.width, +// .height = border.height, +// }; +// scale_box(&obox, m->wlr_output->scale); +// render_rect(m, output_damage, &obox, color); +// } +// } +// } + +static void surface_handle_destroy(struct wl_listener *listener, void *data) +{ struct scene_surface *surface = wl_container_of(listener, surface, destroy); wlr_scene_node_destroy(&surface->scene_surface->buffer->node); wlr_scene_node_destroy(&surface->border->node); @@ -415,8 +478,10 @@ static void surface_handle_destroy(struct wl_listener *listener, void *data) { static void server_handle_new_surface(struct wl_listener *listener, void *data) { + printf("create notify new surface\n"); struct server *server = wl_container_of(listener, server, new_surface); struct wlr_surface *wlr_surface = data; + // wlr_surface->role_data struct scene_surface *surface = calloc(1, sizeof(struct scene_surface)); surface->wlr = wlr_surface; @@ -428,256 +493,240 @@ static void server_handle_new_surface(struct wl_listener *listener, void *data) surface->scene_surface = wlr_scene_surface_create(&server->scene->tree, wlr_surface); - wlr_surface->data = surface; - wlr_scene_node_set_position(&surface->scene_surface->buffer->node, 300, 300); } int setup_server(struct server *server) { - server->uv_loop = uv_default_loop(); - - uv_async_init(uv_default_loop(), &server->async_handler, _async_handler_function); - - /* If we don't provide a renderer, autocreate makes a GLES2 renderer for us. - * The renderer is responsible for defining the various pixel formats it - * supports for shared memory, this configures that for clients. */ - server->renderer = wlr_renderer_autocreate(server->backend); - - wlr_renderer_init_wl_display(server->renderer, server->wl_display); - - server->allocator = wlr_allocator_autocreate(server->backend, server->renderer); - - /* This creates some hands-off wlroots interfaces. The compositor is - * necessary for clients to allocate surfaces and the data device manager - * handles the clipboard. Each of these wlroots interfaces has room for you - * to dig your fingers in and play with their behavior if you want. Note that - * the clients cannot set the selection directly without compositor approval, - * see the setsel() function. */ - server->compositor = wlr_compositor_create(server->wl_display, server->renderer); - - wlr_subcompositor_create(server->wl_display); - - wlr_export_dmabuf_manager_v1_create(server->wl_display); - wlr_screencopy_manager_v1_create(server->wl_display); - wlr_data_control_manager_v1_create(server->wl_display); - wlr_data_device_manager_create(server->wl_display); - wlr_gamma_control_manager_v1_create(server->wl_display); - wlr_primary_selection_v1_device_manager_create(server->wl_display); - wlr_viewporter_create(server->wl_display); - wlr_idle_create(server->wl_display); - wlr_idle_inhibit_v1_create(server->wl_display); - - wlr_xdg_output_manager_v1_create(server->wl_display, server->output_layout); - - /* Set up the xdg-shell. The xdg-shell is a - * Wayland protocol which is used for application windows. For more - * detail on shells, refer to the article: - * - * https://drewdevault.com/2018/07/29/Wayland-shells.html - */ - - server->input_inhibitor_mgr = wlr_input_inhibit_manager_create(server->wl_display); - - /* setup virtual pointer manager*/ - server->virtual_pointer_mgr = wlr_virtual_pointer_manager_v1_create(server->wl_display); - - /* setup virtual keyboard manager */ - server->virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(server->wl_display); - - /* setup relative pointer manager */ - server->relative_pointer_mgr = wlr_relative_pointer_manager_v1_create(server->wl_display); - /* wl_signal_add(&server.virtual_keyboard_mgr->events.new_virtual_keyboard, &new_virtual_keyboard); */ - init_event_handlers(server); - - /* - * Configures a seat, which is a single "seat" at which a user sits and - * operates the computer. This conceptually includes up to one keyboard, - * pointer, touch, and drawing tablet device. We also rig up a listener to - * let us know when new input devices are available on the backend. - */ - server->input_manager = create_input_manager(); - struct seat *seat = create_seat("seat0"); - g_ptr_array_add(server->input_manager->seats, seat); - - server->output_mgr = wlr_output_manager_v1_create(server->wl_display); - wl_signal_add(&server->output_mgr->events.apply, &server->output_mgr_apply); - wl_signal_add(&server->output_mgr->events.test, &server->output_mgr_test); - - server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); - - server->scene = wlr_scene_create(); - server->new_surface.notify = server_handle_new_surface; - wl_signal_add(&server->compositor->events.new_surface, &server->new_surface); + server->uv_loop = uv_default_loop(); + + uv_async_init(uv_default_loop(), &server->async_handler, + _async_handler_function); + + /* If we don't provide a renderer, autocreate makes a GLES2 renderer for us. + * The renderer is responsible for defining the various pixel formats it + * supports for shared memory, this configures that for clients. */ + server->renderer = wlr_renderer_autocreate(server->backend); + + wlr_renderer_init_wl_display(server->renderer, server->wl_display); + + server->allocator = + wlr_allocator_autocreate(server->backend, server->renderer); + + /* This creates some hands-off wlroots interfaces. The compositor is + * necessary for clients to allocate surfaces and the data device manager + * handles the clipboard. Each of these wlroots interfaces has room for you + * to dig your fingers in and play with their behavior if you want. Note that + * the clients cannot set the selection directly without compositor approval, + * see the setsel() function. */ + server->compositor = + wlr_compositor_create(server->wl_display, server->renderer); + + wlr_subcompositor_create(server->wl_display); + + wlr_export_dmabuf_manager_v1_create(server->wl_display); + wlr_screencopy_manager_v1_create(server->wl_display); + wlr_data_control_manager_v1_create(server->wl_display); + wlr_data_device_manager_create(server->wl_display); + wlr_gamma_control_manager_v1_create(server->wl_display); + wlr_primary_selection_v1_device_manager_create(server->wl_display); + wlr_viewporter_create(server->wl_display); + wlr_idle_create(server->wl_display); + wlr_idle_inhibit_v1_create(server->wl_display); + + wlr_xdg_output_manager_v1_create(server->wl_display, server->output_layout); + + /* Set up the xdg-shell. The xdg-shell is a + * Wayland protocol which is used for application windows. For more + * detail on shells, refer to the article: + * + * https://drewdevault.com/2018/07/29/Wayland-shells.html + */ + + server->input_inhibitor_mgr = + wlr_input_inhibit_manager_create(server->wl_display); + + /* setup virtual pointer manager*/ + server->virtual_pointer_mgr = + wlr_virtual_pointer_manager_v1_create(server->wl_display); + + /* setup virtual keyboard manager */ + server->virtual_keyboard_mgr = + wlr_virtual_keyboard_manager_v1_create(server->wl_display); + + /* setup relative pointer manager */ + server->relative_pointer_mgr = + wlr_relative_pointer_manager_v1_create(server->wl_display); + /* wl_signal_add(&server.virtual_keyboard_mgr->events.new_virtual_keyboard, + * &new_virtual_keyboard); */ + init_event_handlers(server); + + /* + * Configures a seat, which is a single "seat" at which a user sits and + * operates the computer. This conceptually includes up to one keyboard, + * pointer, touch, and drawing tablet device. We also rig up a listener to + * let us know when new input devices are available on the backend. + */ + server->input_manager = create_input_manager(); + struct seat *seat = create_seat("seat0"); + g_ptr_array_add(server->input_manager->seats, seat); + + server->output_mgr = wlr_output_manager_v1_create(server->wl_display); + wl_signal_add(&server->output_mgr->events.apply, &server->output_mgr_apply); + wl_signal_add(&server->output_mgr->events.test, &server->output_mgr_test); + + server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); + + server->scene = wlr_scene_create(); + server->new_surface.notify = server_handle_new_surface; + wl_signal_add(&server->compositor->events.new_surface, &server->new_surface); #ifdef JAPOKWM_HAS_XWAYLAND - init_xwayland(server->wl_display, seat); + init_xwayland(server->wl_display, seat); #endif - return 0; + return 0; } -int start_server(char *startup_cmd) -{ - if (setup_server(&server)) { - printf("failed to setup japokwm\n"); - return EXIT_FAILURE; - } +int start_server(char *startup_cmd) { + if (setup_server(&server)) { + printf("failed to setup japokwm\n"); + return EXIT_FAILURE; + } - run(startup_cmd); - return EXIT_SUCCESS; + run(startup_cmd); + return EXIT_SUCCESS; } -int finalize(struct server *server) -{ - finalize_timers(server); - destroy_layout(server->default_layout); - destroy_ring_buffer(server->default_layout_ring); - return 0; +int finalize(struct server *server) { + finalize_timers(server); + destroy_layout(server->default_layout); + destroy_ring_buffer(server->default_layout_ring); + return 0; } -int stop_server() -{ +int stop_server() { #if JAPOKWM_HAS_XWAYLAND - wlr_xwayland_destroy(server.xwayland.wlr_xwayland); + wlr_xwayland_destroy(server.xwayland.wlr_xwayland); #endif - wl_display_destroy_clients(server.wl_display); + wl_display_destroy_clients(server.wl_display); - finalize(&server); + finalize(&server); - close_error_file(); - wlr_output_layout_destroy(server.output_layout); - wl_display_destroy(server.wl_display); - destroy_input_manager(server.input_manager); - destroy_tags(server.tags); + close_error_file(); + wlr_output_layout_destroy(server.output_layout); + wl_display_destroy(server.wl_display); + destroy_input_manager(server.input_manager); + destroy_tags(server.tags); - finalize_lua_api(&server); - return EXIT_SUCCESS; + finalize_lua_api(&server); + return EXIT_SUCCESS; } -int server_get_tag_count() -{ - size_t len = server.default_layout->options->tag_names->len; - return len; +int server_get_tag_count() { + size_t len = server.default_layout->options->tag_names->len; + return len; } -int server_get_tag_key_count() -{ - size_t count = g_hash_table_size(server.tags); - return count; +int server_get_tag_key_count() { + size_t count = g_hash_table_size(server.tags); + return count; } -GList *server_get_tags() -{ - GList *values = g_hash_table_get_values(server.tags); - return values; +GList *server_get_tags() { + GList *values = g_hash_table_get_values(server.tags); + return values; } -struct tag *get_tag(int id) -{ - if (id < 0) - return NULL; - struct tag *tag = g_hash_table_lookup(server.tags, &id); - if (!tag) { - tag = handle_too_few_tags(id); - assert(tag != NULL); - } +struct tag *get_tag(int id) { + if (id < 0) + return NULL; + struct tag *tag = g_hash_table_lookup(server.tags, &id); + if (!tag) { + tag = handle_too_few_tags(id); + assert(tag != NULL); + } - return tag; + return tag; } -struct monitor *server_get_selected_monitor() -{ - return server.selected_monitor; +struct monitor *server_get_selected_monitor() { + return server.selected_monitor; } -void server_set_selected_monitor(struct monitor *m) -{ - server.selected_monitor = m; +void server_set_selected_monitor(struct monitor *m) { + server.selected_monitor = m; } -void server_center_default_cursor_in_monitor(struct monitor *m) -{ - struct seat *seat = input_manager_get_default_seat(); - struct cursor *cursor = seat->cursor; - center_cursor_in_monitor(cursor, m); +void server_center_default_cursor_in_monitor(struct monitor *m) { + struct seat *seat = input_manager_get_default_seat(); + struct cursor *cursor = seat->cursor; + center_cursor_in_monitor(cursor, m); } -BitSet *server_bitset_get_tmp() -{ - if (!server.tmp_bitset) { - server.tmp_bitset = bitset_create(); - } - return server.tmp_bitset; +BitSet *server_bitset_get_tmp() { + if (!server.tmp_bitset) { + server.tmp_bitset = bitset_create(); + } + return server.tmp_bitset; } -BitSet *server_bitset_get_tmp_copy(BitSet *bitset) -{ - BitSet *tmp = server_bitset_get_tmp(); - bitset_assign_bitset(&tmp, bitset); - return tmp; +BitSet *server_bitset_get_tmp_copy(BitSet *bitset) { + BitSet *tmp = server_bitset_get_tmp(); + bitset_assign_bitset(&tmp, bitset); + return tmp; } -BitSet *server_bitset_get_local_tmp() -{ - if (!server.local_tmp_bitset) { - server.local_tmp_bitset = bitset_create(); - } +BitSet *server_bitset_get_local_tmp() { + if (!server.local_tmp_bitset) { + server.local_tmp_bitset = bitset_create(); + } - return server.local_tmp_bitset; + return server.local_tmp_bitset; } -BitSet *server_bitset_get_local_tmp_copy(BitSet *bitset) -{ - BitSet *tmp = server_bitset_get_local_tmp(); - bitset_assign_bitset(&tmp, bitset); - return tmp; +BitSet *server_bitset_get_local_tmp_copy(BitSet *bitset) { + BitSet *tmp = server_bitset_get_local_tmp(); + bitset_assign_bitset(&tmp, bitset); + return tmp; } -struct tag *server_get_selected_tag() -{ +struct tag *server_get_selected_tag() { struct monitor *m = server_get_selected_monitor(); struct tag *tag = monitor_get_active_tag(m); return tag; } -struct layout *server_get_selected_layout() -{ +struct layout *server_get_selected_layout() { struct tag *tag = server_get_selected_tag(); struct layout *lt = tag_get_layout(tag); return lt; } -void server_prohibit_reloading_config() -{ +void server_prohibit_reloading_config() { server.prohibit_reload_config = true; } -void server_allow_reloading_config() -{ - server.prohibit_reload_config = false; -} +void server_allow_reloading_config() { server.prohibit_reload_config = false; } -bool server_is_config_reloading_prohibited() -{ +bool server_is_config_reloading_prohibited() { return server.prohibit_reload_config; } -int cmp_str_bool(const void *s1, const void *s2) -{ - return strcmp(s1, s2) == 0; -} +int cmp_str_bool(const void *s1, const void *s2) { return strcmp(s1, s2) == 0; } -void server_start_keycombo(const char *key_combo_name) -{ +void server_start_keycombo(const char *key_combo_name) { g_ptr_array_add(server.named_key_combos, strdup(key_combo_name)); } -bool server_is_keycombo(const char *key_combo_name) -{ +bool server_is_keycombo(const char *key_combo_name) { guint pos = 0; bool found = g_ptr_array_find_with_equal_func( - server.named_key_combos, - key_combo_name, cmp_str_bool, &pos); + server.named_key_combos, key_combo_name, cmp_str_bool, &pos); return found; } + +struct client *wlr_surface_get_client(struct wlr_surface *wlr_surface) +{ + return wlr_surface->data; +} diff --git a/src/xdg_shell.c b/src/xdg_shell.c index 83f8bffa..8683557f 100644 --- a/src/xdg_shell.c +++ b/src/xdg_shell.c @@ -49,6 +49,7 @@ void create_notify_xdg(struct wl_listener *listener, void *data) surface.xdg = xdg_surface; /* Allocate a Client for this surface */ struct client *c = xdg_surface->data = create_client(XDG_SHELL, surface); + xdg_surface->surface->data = c; /* Tell the client not to try anything fancy */ wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, WLR_EDGE_TOP | diff --git a/src/xwayland.c b/src/xwayland.c index acfaad9f..98ca3a90 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -46,7 +46,7 @@ void create_notifyx11(struct wl_listener *listener, void *data) union surface_t surface; surface.xwayland = xwayland_surface; - struct client *c = xwayland_surface->data = create_client(X11_MANAGED, surface); + struct client *c = xwayland_surface->surface->data = create_client(X11_MANAGED, surface); // set default value will be overriden on maprequest /* Listen to the various events it can emit */ From 0222b0a8ba3abf966abce0f51aba38c16f817782 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 11:49:07 +0200 Subject: [PATCH 13/37] fix --- include/client.h | 2 ++ include/server.h | 4 ++- src/client.c | 15 +++++++++++ src/server.c | 60 +++++++++++++++++++++++++++++++++++++------- src/tile/tileUtils.c | 2 +- src/xwayland.c | 5 +++- 6 files changed, 76 insertions(+), 12 deletions(-) diff --git a/include/client.h b/include/client.h index fb1b0ab1..3860c309 100644 --- a/include/client.h +++ b/include/client.h @@ -34,6 +34,8 @@ struct client { struct wl_listener new_popup; struct wl_listener new_subsurface; + struct scene_surface *scene_surface; + enum shell type; const char *title; const char *app_id; diff --git a/include/server.h b/include/server.h index 10e2f4ef..68f2bb14 100644 --- a/include/server.h +++ b/include/server.h @@ -26,7 +26,7 @@ struct scene_surface { struct wlr_surface *wlr; struct wlr_scene_surface *scene_surface; - struct wlr_scene_rect *border; + struct wlr_scene_rect *borders[4]; struct wl_list link; struct wl_listener commit; @@ -150,6 +150,8 @@ struct function_data { char *output; }; +#define BORDER_COUNT 4 + extern struct server server; void init_server(); diff --git a/src/client.c b/src/client.c index 51f51a83..9f7e23d9 100644 --- a/src/client.c +++ b/src/client.c @@ -27,6 +27,21 @@ struct client *create_client(enum shell shell_type, union surface_t surface) c->type = shell_type; c->surface = surface; + // TODO: this is a hack. first wlr_surface->data is filled with the surface + // then we will fill it with the corro + switch (shell_type) { + case XDG_SHELL: + c->scene_surface = surface.xdg->surface->data; + break; + case LAYER_SHELL: + c->scene_surface = surface.layer->surface->data; + break; + case X11_MANAGED: + case X11_UNMANAGED: + c->scene_surface = surface.xwayland->data; + break; + } + return c; } diff --git a/src/server.c b/src/server.c index 9eb595d8..2cbe475c 100644 --- a/src/server.c +++ b/src/server.c @@ -37,6 +37,7 @@ #include "utils/coreUtils.h" #include "utils/parseConfigUtils.h" #include "xdg_shell.h" +#include "container.h" #define XDG_SHELL_VERSION 2 @@ -414,15 +415,46 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { struct client *c = wlr_surface_get_client(surface->wlr); struct container *con = c->con; + + if (!con->has_border) + return; + + enum wlr_edges hidden_edges = WLR_EDGE_NONE; + struct tag *tag = monitor_get_active_tag(m); + struct layout *lt = tag_get_layout(tag); + if (lt->options->smart_hidden_edges) { + if (tag->visible_con_set->tiled_containers->len <= 1) { + hidden_edges = container_update_hidden_edges(con, borders, + lt->options->hidden_edges); + } + } else { + hidden_edges = container_update_hidden_edges(con, borders, + lt->options->hidden_edges); + } + + struct wlr_box *borders = (struct wlr_box[4]) { container_get_current_border_geom(con, WLR_EDGE_TOP), - container_get_current_border_geom(con, WLR_EDGE_BOTTOM), - container_get_current_border_geom(con, WLR_EDGE_LEFT), - container_get_current_border_geom(con, WLR_EDGE_RIGHT), + container_get_current_border_geom(con, WLR_EDGE_BOTTOM), + container_get_current_border_geom(con, WLR_EDGE_LEFT), + container_get_current_border_geom(con, WLR_EDGE_RIGHT), }; - for (int i = 0; i < 4; i++) { - struct wlr_box border = borders[i]; - scale_box(&obox, m->wlr_output->scale); + + struct monitor *m = container_get_monitor(con); + struct container *sel = monitor_get_focused_container(m); + const struct color color = (con == sel) ? lt->options->focus_color : + lt->options->border_color; + + for (int i = 0; i < BORDER_COUNT; i++) { + struct wlr_scene_rect *border = surface->borders[i]; + struct wlr_box geom = borders[i]; + + wlr_scene_node_set_position(&border->node, geom.x, geom.y); + wlr_scene_rect_set_size(border, geom.width, geom.height); + + float border_color[4]; + color_to_wlr_color(border_color, color); + wlr_scene_rect_set_color(border, border_color); } } @@ -449,7 +481,8 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { // /* Draw window borders */ // struct container *sel = monitor_get_focused_container(m); // const struct color color = (con == sel) ? lt->options->focus_color : -// lt->options->border_color; for (int i = 0; i < 4; i++) { +// lt->options->border_color; +// for (int i = 0; i < 4; i++) { // if ((hidden_edges & (1 << i)) == 0) { // struct wlr_box border = borders[i]; // double ox = border.x; @@ -471,7 +504,10 @@ static void surface_handle_destroy(struct wl_listener *listener, void *data) { struct scene_surface *surface = wl_container_of(listener, surface, destroy); wlr_scene_node_destroy(&surface->scene_surface->buffer->node); - wlr_scene_node_destroy(&surface->border->node); + for (int i = 0; i < BORDER_COUNT; i++) { + struct wlr_scene_rect *border = surface->borders[i]; + wlr_scene_node_destroy(&border->node); + } wl_list_remove(&surface->destroy.link); free(surface); } @@ -493,7 +529,13 @@ static void server_handle_new_surface(struct wl_listener *listener, void *data) surface->scene_surface = wlr_scene_surface_create(&server->scene->tree, wlr_surface); - wlr_scene_node_set_position(&surface->scene_surface->buffer->node, 300, 300); + for (int i = 0; i < BORDER_COUNT; i++) { + surface->borders[i] = + wlr_scene_rect_create(&server->scene->tree, + 0, 0, (float[4]){ 1.0f, 0.0f, 0.0f, 1 }); + } + + wlr_surface->data = surface; } int setup_server(struct server *server) diff --git a/src/tile/tileUtils.c b/src/tile/tileUtils.c index c006fef1..7063116f 100644 --- a/src/tile/tileUtils.c +++ b/src/tile/tileUtils.c @@ -304,7 +304,7 @@ void container_update_size(struct container *con) container_set_current_geom(con, con_geom); } - struct scene_surface *surface = get_wlrsurface(con->client)->data; + struct scene_surface *surface = con->client->scene_surface; wlr_scene_node_set_position(&surface->scene_surface->buffer->node, con_geom.x, con_geom.y); /* wlroots makes this a no-op if size hasn't changed */ switch (con->client->type) { diff --git a/src/xwayland.c b/src/xwayland.c index 98ca3a90..5712d4ac 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -46,7 +46,7 @@ void create_notifyx11(struct wl_listener *listener, void *data) union surface_t surface; surface.xwayland = xwayland_surface; - struct client *c = xwayland_surface->surface->data = create_client(X11_MANAGED, surface); + struct client *c = xwayland_surface->data = create_client(X11_MANAGED, surface); // set default value will be overriden on maprequest /* Listen to the various events it can emit */ @@ -144,6 +144,9 @@ void maprequestx11(struct wl_listener *listener, void *data) c->type = xwayland_surface->override_redirect ? X11_UNMANAGED : X11_MANAGED; + c->scene_surface = xwayland_surface->surface->data; + xwayland_surface->surface->data = c; + struct container *con = c->con; con->tag_id = m->tag_id; From 6f64b0c5b29d71eefa28f907992509c13bef35ab Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 12:01:13 +0200 Subject: [PATCH 14/37] fix stuff --- include/server.h | 16 +----- src/meson.build | 1 + src/server.c | 133 ----------------------------------------------- 3 files changed, 2 insertions(+), 148 deletions(-) diff --git a/include/server.h b/include/server.h index 68f2bb14..d239cd60 100644 --- a/include/server.h +++ b/include/server.h @@ -22,16 +22,7 @@ #include "input_manager.h" #include "utils/coreUtils.h" #include "bitset/bitset.h" - -struct scene_surface { - struct wlr_surface *wlr; - struct wlr_scene_surface *scene_surface; - struct wlr_scene_rect *borders[4]; - struct wl_list link; - - struct wl_listener commit; - struct wl_listener destroy; -}; +#include "render.h" struct server { bool is_running; @@ -150,8 +141,6 @@ struct function_data { char *output; }; -#define BORDER_COUNT 4 - extern struct server server; void init_server(); @@ -191,7 +180,4 @@ BitSet *server_bitset_get_local_tmp_copy(BitSet *bitset); struct tag *server_get_selected_tag(); struct layout *server_get_selected_layout(); - -struct client *wlr_surface_get_client(struct wlr_surface *wlr_surface); -struct container *wlr_surface_get_container(struct wlr_surface *wlr_surface); #endif /* SERVER_H */ diff --git a/src/meson.build b/src/meson.build index 2035653a..8c5f03ad 100644 --- a/src/meson.build +++ b/src/meson.build @@ -75,6 +75,7 @@ srcs = files( 'list_sets/container_stack_set.c', 'list_sets/focus_stack_set.c', 'list_sets/list_set.c', + 'render.c', 'rules/mon_rule.c', 'rules/rule.c', 'tile/tileUtils.c', diff --git a/src/server.c b/src/server.c index 2cbe475c..30d1aa83 100644 --- a/src/server.c +++ b/src/server.c @@ -410,134 +410,6 @@ static void _async_handler_function(struct uv_async_s *arg) { free(data); } -static void surface_handle_commit(struct wl_listener *listener, void *data) { - struct scene_surface *surface = wl_container_of(listener, surface, commit); - - struct client *c = wlr_surface_get_client(surface->wlr); - struct container *con = c->con; - - if (!con->has_border) - return; - - enum wlr_edges hidden_edges = WLR_EDGE_NONE; - struct tag *tag = monitor_get_active_tag(m); - struct layout *lt = tag_get_layout(tag); - if (lt->options->smart_hidden_edges) { - if (tag->visible_con_set->tiled_containers->len <= 1) { - hidden_edges = container_update_hidden_edges(con, borders, - lt->options->hidden_edges); - } - } else { - hidden_edges = container_update_hidden_edges(con, borders, - lt->options->hidden_edges); - } - - - struct wlr_box *borders = (struct wlr_box[4]) { - container_get_current_border_geom(con, WLR_EDGE_TOP), - container_get_current_border_geom(con, WLR_EDGE_BOTTOM), - container_get_current_border_geom(con, WLR_EDGE_LEFT), - container_get_current_border_geom(con, WLR_EDGE_RIGHT), - }; - - struct monitor *m = container_get_monitor(con); - struct container *sel = monitor_get_focused_container(m); - const struct color color = (con == sel) ? lt->options->focus_color : - lt->options->border_color; - - for (int i = 0; i < BORDER_COUNT; i++) { - struct wlr_scene_rect *border = surface->borders[i]; - struct wlr_box geom = borders[i]; - - wlr_scene_node_set_position(&border->node, geom.x, geom.y); - wlr_scene_rect_set_size(border, geom.width, geom.height); - - float border_color[4]; - color_to_wlr_color(border_color, color); - wlr_scene_rect_set_color(border, border_color); - } -} - -// static void render_borders(struct container *con, struct monitor *m, -// pixman_region32_t *output_damage) -// { -// // TODO: reimplement me -// if (!con->has_border) -// return; -// -// enum wlr_edges hidden_edges = WLR_EDGE_NONE; -// struct tag *tag = monitor_get_active_tag(m); -// struct layout *lt = tag_get_layout(tag); -// if (lt->options->smart_hidden_edges) { -// if (tag->visible_con_set->tiled_containers->len <= 1) { -// hidden_edges = container_update_hidden_edges(con, borders, -// lt->options->hidden_edges); -// } -// } else { -// hidden_edges = container_update_hidden_edges(con, borders, -// lt->options->hidden_edges); -// } -// -// /* Draw window borders */ -// struct container *sel = monitor_get_focused_container(m); -// const struct color color = (con == sel) ? lt->options->focus_color : -// lt->options->border_color; -// for (int i = 0; i < 4; i++) { -// if ((hidden_edges & (1 << i)) == 0) { -// struct wlr_box border = borders[i]; -// double ox = border.x; -// double oy = border.y; -// wlr_output_layout_output_coords(server.output_layout, -// m->wlr_output, &ox, &oy); struct wlr_box obox = { -// .x = ox, -// .y = oy, -// .width = border.width, -// .height = border.height, -// }; -// scale_box(&obox, m->wlr_output->scale); -// render_rect(m, output_damage, &obox, color); -// } -// } -// } - -static void surface_handle_destroy(struct wl_listener *listener, void *data) -{ - struct scene_surface *surface = wl_container_of(listener, surface, destroy); - wlr_scene_node_destroy(&surface->scene_surface->buffer->node); - for (int i = 0; i < BORDER_COUNT; i++) { - struct wlr_scene_rect *border = surface->borders[i]; - wlr_scene_node_destroy(&border->node); - } - wl_list_remove(&surface->destroy.link); - free(surface); -} - -static void server_handle_new_surface(struct wl_listener *listener, void *data) -{ - printf("create notify new surface\n"); - struct server *server = wl_container_of(listener, server, new_surface); - struct wlr_surface *wlr_surface = data; - // wlr_surface->role_data - - struct scene_surface *surface = calloc(1, sizeof(struct scene_surface)); - surface->wlr = wlr_surface; - surface->commit.notify = surface_handle_commit; - wl_signal_add(&wlr_surface->events.commit, &surface->commit); - surface->destroy.notify = surface_handle_destroy; - wl_signal_add(&wlr_surface->events.destroy, &surface->destroy); - - surface->scene_surface = - wlr_scene_surface_create(&server->scene->tree, wlr_surface); - - for (int i = 0; i < BORDER_COUNT; i++) { - surface->borders[i] = - wlr_scene_rect_create(&server->scene->tree, - 0, 0, (float[4]){ 1.0f, 0.0f, 0.0f, 1 }); - } - - wlr_surface->data = surface; -} - int setup_server(struct server *server) { server->uv_loop = uv_default_loop(); @@ -767,8 +639,3 @@ bool server_is_keycombo(const char *key_combo_name) { server.named_key_combos, key_combo_name, cmp_str_bool, &pos); return found; } - -struct client *wlr_surface_get_client(struct wlr_surface *wlr_surface) -{ - return wlr_surface->data; -} From 1553de2ef64df66953806e8be8cec4c3c62de8b2 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 12:01:23 +0200 Subject: [PATCH 15/37] add files --- include/render.h | 22 +++++++ src/render.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 include/render.h create mode 100644 src/render.c diff --git a/include/render.h b/include/render.h new file mode 100644 index 00000000..7c6247e5 --- /dev/null +++ b/include/render.h @@ -0,0 +1,22 @@ +#ifndef RENDER_H +#define RENDER_H + +#include + +#define BORDER_COUNT 4 + +struct scene_surface { + struct wlr_surface *wlr; + struct wlr_scene_surface *scene_surface; + struct wlr_scene_rect *borders[4]; + struct wl_list link; + + struct wl_listener commit; + struct wl_listener destroy; +}; + +void server_handle_new_surface(struct wl_listener *listener, void *data); + +struct client *wlr_surface_get_client(struct wlr_surface *wlr_surface); + +#endif /* RENDER_H */ diff --git a/src/render.c b/src/render.c new file mode 100644 index 00000000..7cb64c1f --- /dev/null +++ b/src/render.c @@ -0,0 +1,147 @@ +#include "render.h" + +#include +#include + +#include "container.h" +#include "client.h" +#include "tag.h" +#include "monitor.h" +#include "layout.h" + +static void surface_handle_destroy(struct wl_listener *listener, void *data) +{ + struct scene_surface *surface = wl_container_of(listener, surface, destroy); + wlr_scene_node_destroy(&surface->scene_surface->buffer->node); + for (int i = 0; i < BORDER_COUNT; i++) { + struct wlr_scene_rect *border = surface->borders[i]; + wlr_scene_node_destroy(&border->node); + } + wl_list_remove(&surface->destroy.link); + free(surface); +} + +static void surface_handle_commit(struct wl_listener *listener, void *data) { + struct scene_surface *surface = wl_container_of(listener, surface, commit); + + struct client *c = wlr_surface_get_client(surface->wlr); + struct container *con = c->con; + + if (!con->has_border) { + for (int i = 0; i < BORDER_COUNT; i++) { + struct wlr_scene_rect *border = surface->borders[i]; + wlr_scene_node_set_enabled(&border->node, false); + } + } + + enum wlr_edges hidden_edges = WLR_EDGE_NONE; + struct tag *tag = monitor_get_active_tag(m); + struct layout *lt = tag_get_layout(tag); + if (lt->options->smart_hidden_edges) { + if (tag->visible_con_set->tiled_containers->len <= 1) { + hidden_edges = container_update_hidden_edges(con, borders, + lt->options->hidden_edges); + } + } else { + hidden_edges = container_update_hidden_edges(con, borders, + lt->options->hidden_edges); + } + + + struct wlr_box *borders = (struct wlr_box[4]) { + container_get_current_border_geom(con, WLR_EDGE_TOP), + container_get_current_border_geom(con, WLR_EDGE_BOTTOM), + container_get_current_border_geom(con, WLR_EDGE_LEFT), + container_get_current_border_geom(con, WLR_EDGE_RIGHT), + }; + + struct monitor *m = container_get_monitor(con); + struct container *sel = monitor_get_focused_container(m); + const struct color color = (con == sel) ? lt->options->focus_color : + lt->options->border_color; + + for (int i = 0; i < BORDER_COUNT; i++) { + struct wlr_scene_rect *border = surface->borders[i]; + struct wlr_box geom = borders[i]; + + wlr_scene_node_set_position(&border->node, geom.x, geom.y); + wlr_scene_rect_set_size(border, geom.width, geom.height); + + float border_color[4]; + color_to_wlr_color(border_color, color); + wlr_scene_rect_set_color(border, border_color); + } +} + +// static void render_borders(struct container *con, struct monitor *m, +// pixman_region32_t *output_damage) +// { +// // TODO: reimplement me +// if (!con->has_border) +// return; +// +// enum wlr_edges hidden_edges = WLR_EDGE_NONE; +// struct tag *tag = monitor_get_active_tag(m); +// struct layout *lt = tag_get_layout(tag); +// if (lt->options->smart_hidden_edges) { +// if (tag->visible_con_set->tiled_containers->len <= 1) { +// hidden_edges = container_update_hidden_edges(con, borders, +// lt->options->hidden_edges); +// } +// } else { +// hidden_edges = container_update_hidden_edges(con, borders, +// lt->options->hidden_edges); +// } +// +// /* Draw window borders */ +// struct container *sel = monitor_get_focused_container(m); +// const struct color color = (con == sel) ? lt->options->focus_color : +// lt->options->border_color; +// for (int i = 0; i < 4; i++) { +// if ((hidden_edges & (1 << i)) == 0) { +// struct wlr_box border = borders[i]; +// double ox = border.x; +// double oy = border.y; +// wlr_output_layout_output_coords(server.output_layout, +// m->wlr_output, &ox, &oy); struct wlr_box obox = { +// .x = ox, +// .y = oy, +// .width = border.width, +// .height = border.height, +// }; +// scale_box(&obox, m->wlr_output->scale); +// render_rect(m, output_damage, &obox, color); +// } +// } +// } + +void server_handle_new_surface(struct wl_listener *listener, void *data) +{ + printf("create notify new surface\n"); + struct server *server = wl_container_of(listener, server, new_surface); + struct wlr_surface *wlr_surface = data; + // wlr_surface->role_data + + struct scene_surface *surface = calloc(1, sizeof(struct scene_surface)); + surface->wlr = wlr_surface; + surface->commit.notify = surface_handle_commit; + wl_signal_add(&wlr_surface->events.commit, &surface->commit); + surface->destroy.notify = surface_handle_destroy; + wl_signal_add(&wlr_surface->events.destroy, &surface->destroy); + + surface->scene_surface = + wlr_scene_surface_create(&server->scene->tree, wlr_surface); + + for (int i = 0; i < BORDER_COUNT; i++) { + surface->borders[i] = + wlr_scene_rect_create(&server->scene->tree, + 0, 0, (float[4]){ 1.0f, 0.0f, 0.0f, 1 }); + } + + wlr_surface->data = surface; +} + +struct client *wlr_surface_get_client(struct wlr_surface *wlr_surface) +{ + return wlr_surface->data; +} From 1c29593171116625dc1e4475b1f81ce01f2c23a4 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 12:09:24 +0200 Subject: [PATCH 16/37] feat: implement ground structure for scene_graph --- src/render.c | 63 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/src/render.c b/src/render.c index 7cb64c1f..56484cf2 100644 --- a/src/render.c +++ b/src/render.c @@ -8,6 +8,8 @@ #include "tag.h" #include "monitor.h" #include "layout.h" +#include "list_sets/container_stack_set.h" +#include "root.h" static void surface_handle_destroy(struct wl_listener *listener, void *data) { @@ -21,6 +23,41 @@ static void surface_handle_destroy(struct wl_listener *listener, void *data) free(surface); } +// TODO refactor the name it doesn't represent what this does perfectly +// returns the newly accquired hidden edges +static enum wlr_edges container_update_hidden_edges(struct container *con, struct wlr_box *borders, enum wlr_edges hidden_edges) +{ + struct monitor *m = container_get_monitor(con); + + enum wlr_edges containers_hidden_edges = WLR_EDGE_NONE; + struct wlr_box con_geom = container_get_current_geom(con); + // int border_width = container_get_border_width(con); + // hide edges if needed + if (hidden_edges & WLR_EDGE_LEFT) { + if (con_geom.x == m->root->geom.x) { + containers_hidden_edges |= WLR_EDGE_LEFT; + } + } + if (hidden_edges & WLR_EDGE_RIGHT) { + if (is_approx_equal(con_geom.x + con_geom.width, m->root->geom.x + m->root->geom.width, 3)) { + containers_hidden_edges |= WLR_EDGE_RIGHT; + } + } + if (hidden_edges & WLR_EDGE_TOP) { + if (con_geom.y == m->root->geom.y) { + containers_hidden_edges |= WLR_EDGE_TOP; + } + } + if (hidden_edges & WLR_EDGE_BOTTOM) { + if (is_approx_equal(con_geom.y + con_geom.height, m->root->geom.y + m->root->geom.height, 3)) { + containers_hidden_edges |= WLR_EDGE_BOTTOM; + } + } + + container_set_hidden_edges(con, containers_hidden_edges); + return containers_hidden_edges; +} + static void surface_handle_commit(struct wl_listener *listener, void *data) { struct scene_surface *surface = wl_container_of(listener, surface, commit); @@ -32,9 +69,18 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { struct wlr_scene_rect *border = surface->borders[i]; wlr_scene_node_set_enabled(&border->node, false); } + return; } + struct wlr_box *borders = (struct wlr_box[4]) { + container_get_current_border_geom(con, WLR_EDGE_TOP), + container_get_current_border_geom(con, WLR_EDGE_BOTTOM), + container_get_current_border_geom(con, WLR_EDGE_LEFT), + container_get_current_border_geom(con, WLR_EDGE_RIGHT), + }; + enum wlr_edges hidden_edges = WLR_EDGE_NONE; + struct monitor *m = container_get_monitor(con); struct tag *tag = monitor_get_active_tag(m); struct layout *lt = tag_get_layout(tag); if (lt->options->smart_hidden_edges) { @@ -47,15 +93,6 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { lt->options->hidden_edges); } - - struct wlr_box *borders = (struct wlr_box[4]) { - container_get_current_border_geom(con, WLR_EDGE_TOP), - container_get_current_border_geom(con, WLR_EDGE_BOTTOM), - container_get_current_border_geom(con, WLR_EDGE_LEFT), - container_get_current_border_geom(con, WLR_EDGE_RIGHT), - }; - - struct monitor *m = container_get_monitor(con); struct container *sel = monitor_get_focused_container(m); const struct color color = (con == sel) ? lt->options->focus_color : lt->options->border_color; @@ -64,6 +101,13 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { struct wlr_scene_rect *border = surface->borders[i]; struct wlr_box geom = borders[i]; + bool is_hidden = hidden_edges & (1 << i); + // hide or show the border + wlr_scene_node_set_enabled(&border->node, !is_hidden); + if (is_hidden) { + continue; + } + wlr_scene_node_set_position(&border->node, geom.x, geom.y); wlr_scene_rect_set_size(border, geom.width, geom.height); @@ -73,6 +117,7 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { } } + // static void render_borders(struct container *con, struct monitor *m, // pixman_region32_t *output_damage) // { From 13143db87775b7ee1bbf9baf3d567f52b207b21e Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 12:35:56 +0200 Subject: [PATCH 17/37] "f --- src/render.c | 44 ++------------------------------------------ 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/src/render.c b/src/render.c index 56484cf2..f8cb9f18 100644 --- a/src/render.c +++ b/src/render.c @@ -64,6 +64,8 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { struct client *c = wlr_surface_get_client(surface->wlr); struct container *con = c->con; + wlr_scene_node_set_enabled(&surface->scene_surface->node, true); + if (!con->has_border) { for (int i = 0; i < BORDER_COUNT; i++) { struct wlr_scene_rect *border = surface->borders[i]; @@ -118,48 +120,6 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { } -// static void render_borders(struct container *con, struct monitor *m, -// pixman_region32_t *output_damage) -// { -// // TODO: reimplement me -// if (!con->has_border) -// return; -// -// enum wlr_edges hidden_edges = WLR_EDGE_NONE; -// struct tag *tag = monitor_get_active_tag(m); -// struct layout *lt = tag_get_layout(tag); -// if (lt->options->smart_hidden_edges) { -// if (tag->visible_con_set->tiled_containers->len <= 1) { -// hidden_edges = container_update_hidden_edges(con, borders, -// lt->options->hidden_edges); -// } -// } else { -// hidden_edges = container_update_hidden_edges(con, borders, -// lt->options->hidden_edges); -// } -// -// /* Draw window borders */ -// struct container *sel = monitor_get_focused_container(m); -// const struct color color = (con == sel) ? lt->options->focus_color : -// lt->options->border_color; -// for (int i = 0; i < 4; i++) { -// if ((hidden_edges & (1 << i)) == 0) { -// struct wlr_box border = borders[i]; -// double ox = border.x; -// double oy = border.y; -// wlr_output_layout_output_coords(server.output_layout, -// m->wlr_output, &ox, &oy); struct wlr_box obox = { -// .x = ox, -// .y = oy, -// .width = border.width, -// .height = border.height, -// }; -// scale_box(&obox, m->wlr_output->scale); -// render_rect(m, output_damage, &obox, color); -// } -// } -// } - void server_handle_new_surface(struct wl_listener *listener, void *data) { printf("create notify new surface\n"); From 228b0074a7080c7297c817870e921179aa2997a5 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 12:36:57 +0200 Subject: [PATCH 18/37] "f --- src/render.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/render.c b/src/render.c index f8cb9f18..1cb12f3c 100644 --- a/src/render.c +++ b/src/render.c @@ -63,7 +63,10 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { struct client *c = wlr_surface_get_client(surface->wlr); struct container *con = c->con; + struct monitor *m = container_get_monitor(con); + if (!container_viewable_on_monitor(m, con)) + continue; wlr_scene_node_set_enabled(&surface->scene_surface->node, true); if (!con->has_border) { @@ -82,7 +85,6 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { }; enum wlr_edges hidden_edges = WLR_EDGE_NONE; - struct monitor *m = container_get_monitor(con); struct tag *tag = monitor_get_active_tag(m); struct layout *lt = tag_get_layout(tag); if (lt->options->smart_hidden_edges) { From 08b1391fb0a837d7e0532a2c965a191eae2a7a2b Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 13:41:11 +0200 Subject: [PATCH 19/37] fix stuff --- include/render.h | 2 ++ include/server.h | 6 ++++++ src/render.c | 14 ++++++-------- src/server.c | 6 ++++++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/include/render.h b/include/render.h index 7c6247e5..ac876dd4 100644 --- a/include/render.h +++ b/include/render.h @@ -7,6 +7,7 @@ struct scene_surface { struct wlr_surface *wlr; + struct wlr_scene_tree *surface_tree; struct wlr_scene_surface *scene_surface; struct wlr_scene_rect *borders[4]; struct wl_list link; @@ -15,6 +16,7 @@ struct scene_surface { struct wl_listener destroy; }; +void scene_create(struct wlr_scene **scene); void server_handle_new_surface(struct wl_listener *listener, void *data); struct client *wlr_surface_get_client(struct wlr_surface *wlr_surface); diff --git a/include/server.h b/include/server.h index d239cd60..ebb21678 100644 --- a/include/server.h +++ b/include/server.h @@ -47,6 +47,12 @@ struct server { struct event_handler *event_handler; struct wlr_scene *scene; + struct wlr_scene_tree *pending; + struct wlr_scene_tree *background; + struct wlr_scene_tree *foreground; + struct wlr_scene_tree *floating; + + struct wl_listener new_surface; struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr; diff --git a/src/render.c b/src/render.c index 1cb12f3c..45fa8dd3 100644 --- a/src/render.c +++ b/src/render.c @@ -10,15 +10,16 @@ #include "layout.h" #include "list_sets/container_stack_set.h" #include "root.h" +#include "tagset.h" static void surface_handle_destroy(struct wl_listener *listener, void *data) { struct scene_surface *surface = wl_container_of(listener, surface, destroy); - wlr_scene_node_destroy(&surface->scene_surface->buffer->node); for (int i = 0; i < BORDER_COUNT; i++) { struct wlr_scene_rect *border = surface->borders[i]; wlr_scene_node_destroy(&border->node); } + wlr_scene_node_destroy(&surface->scene_surface->buffer->node); wl_list_remove(&surface->destroy.link); free(surface); } @@ -65,10 +66,6 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { struct container *con = c->con; struct monitor *m = container_get_monitor(con); - if (!container_viewable_on_monitor(m, con)) - continue; - wlr_scene_node_set_enabled(&surface->scene_surface->node, true); - if (!con->has_border) { for (int i = 0; i < BORDER_COUNT; i++) { struct wlr_scene_rect *border = surface->borders[i]; @@ -121,7 +118,6 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { } } - void server_handle_new_surface(struct wl_listener *listener, void *data) { printf("create notify new surface\n"); @@ -136,12 +132,14 @@ void server_handle_new_surface(struct wl_listener *listener, void *data) surface->destroy.notify = surface_handle_destroy; wl_signal_add(&wlr_surface->events.destroy, &surface->destroy); + surface->surface_tree = wlr_scene_tree_create(server->pending); + surface->scene_surface = - wlr_scene_surface_create(&server->scene->tree, wlr_surface); + wlr_scene_surface_create(surface->surface_tree, wlr_surface); for (int i = 0; i < BORDER_COUNT; i++) { surface->borders[i] = - wlr_scene_rect_create(&server->scene->tree, + wlr_scene_rect_create(surface->surface_tree, 0, 0, (float[4]){ 1.0f, 0.0f, 0.0f, 1 }); } diff --git a/src/server.c b/src/server.c index 30d1aa83..1a3c834f 100644 --- a/src/server.c +++ b/src/server.c @@ -492,6 +492,12 @@ int setup_server(struct server *server) server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); server->scene = wlr_scene_create(); + struct wlr_scene *server_scene = server->scene; + server->background = wlr_scene_tree_create(&server_scene->tree); + server->foreground = wlr_scene_tree_create(&server_scene->tree); + server->floating = wlr_scene_tree_create(&server_scene->tree); + server->pending = wlr_scene_tree_create(&server_scene->tree); + server->new_surface.notify = server_handle_new_surface; wl_signal_add(&server->compositor->events.new_surface, &server->new_surface); From 5c002c0c60777ee85bd2b5d2c0a39bd590d413f3 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 15:08:10 +0200 Subject: [PATCH 20/37] feat: improve scene graph implementation --- include/container.h | 4 + src/client.c | 1 + src/container.c | 170 +++++++++++++++++++++++++++++++++++-------- src/render.c | 87 +--------------------- src/tile/tileUtils.c | 12 +++ 5 files changed, 157 insertions(+), 117 deletions(-) diff --git a/include/container.h b/include/container.h index 720d42e0..2403938c 100644 --- a/include/container.h +++ b/include/container.h @@ -100,6 +100,10 @@ void container_set_floating(struct container *con, void (*fix_position)(struct c void container_set_hidden(struct container *con, bool b); void container_set_hidden_at_tag(struct container *con, bool b, struct tag *tag); void set_container_monitor(struct container *con, struct monitor *m); +void container_update_border(struct container *con); +void container_update_border_geometry(struct container *con); +void container_update_border_color(struct container *con); +void container_update_border_visibility(struct container *con); void resize_container(struct container *con, struct wlr_cursor *cursor, int dx, int dy); void resize_container_in_layout(struct container *con, struct wlr_box geom); void move_container(struct container *con, struct wlr_cursor *cursor, int offsetx, int offsety); diff --git a/src/client.c b/src/client.c index 9f7e23d9..0d155c4a 100644 --- a/src/client.c +++ b/src/client.c @@ -119,6 +119,7 @@ static void unfocus_client(struct client *c) default: break; } + container_update_border_color(c->con); } void focus_surface(struct seat *seat, struct wlr_surface *surface) diff --git a/src/container.c b/src/container.c index ff997c11..b2a8a57b 100644 --- a/src/container.c +++ b/src/container.c @@ -28,6 +28,7 @@ #include "lib/lib_container.h" #include "lib/lib_layout.h" #include "lib/lib_geom.h" +#include "root.h" static void add_container_to_tag(struct container *con, struct tag *tag); @@ -955,44 +956,21 @@ struct wlr_box container_get_current_content_geom(struct container *con) struct wlr_box container_get_current_border_geom(struct container *con, enum wlr_edges dir) { struct wlr_box geom = container_get_current_geom(con); - enum wlr_edges hidden_edges = container_get_hidden_edges(con); + struct direction_value d = container_get_border_width(con); switch (dir) { case WLR_EDGE_TOP: - { - if (!(hidden_edges & WLR_EDGE_TOP)) { - struct direction_value d = container_get_border_width(con); - geom.height = d.top; - } - break; - } + geom.height = d.top; + break; case WLR_EDGE_BOTTOM: - { - if (!(hidden_edges & WLR_EDGE_BOTTOM)) { - struct direction_value d = container_get_border_width(con); - geom.y += geom.height - d.bottom; - geom.height = d.bottom; - } - break; - } + geom.y += geom.height - d.bottom; + geom.height = d.bottom; break; case WLR_EDGE_LEFT: - { - if (!(hidden_edges & WLR_EDGE_LEFT)) { - struct direction_value d = container_get_border_width(con); - geom.width = d.left; - } - break; - } + geom.width = d.left; break; case WLR_EDGE_RIGHT: - { - if (!(hidden_edges & WLR_EDGE_RIGHT)) { - struct direction_value d = container_get_border_width(con); - geom.x += geom.width - d.right; - geom.width = d.right; - } - break; - } + geom.x += geom.width - d.right; + geom.width = d.right; break; default: break; @@ -1081,6 +1059,136 @@ struct direction_value container_get_border_width(struct container *con) return property->border_width; } +// TODO refactor the name it doesn't represent what this does perfectly +// returns the newly accquired hidden edges +static enum wlr_edges container_update_hidden_edges(struct container *con, struct wlr_box *borders, enum wlr_edges hidden_edges) +{ + struct monitor *m = container_get_monitor(con); + + enum wlr_edges containers_hidden_edges = WLR_EDGE_NONE; + struct wlr_box con_geom = container_get_current_geom(con); + // int border_width = container_get_border_width(con); + // hide edges if needed + if (hidden_edges & WLR_EDGE_LEFT) { + if (con_geom.x == m->root->geom.x) { + containers_hidden_edges |= WLR_EDGE_LEFT; + } + } + if (hidden_edges & WLR_EDGE_RIGHT) { + if (is_approx_equal(con_geom.x + con_geom.width, m->root->geom.x + m->root->geom.width, 3)) { + containers_hidden_edges |= WLR_EDGE_RIGHT; + } + } + if (hidden_edges & WLR_EDGE_TOP) { + if (con_geom.y == m->root->geom.y) { + containers_hidden_edges |= WLR_EDGE_TOP; + } + } + if (hidden_edges & WLR_EDGE_BOTTOM) { + if (is_approx_equal(con_geom.y + con_geom.height, m->root->geom.y + m->root->geom.height, 3)) { + containers_hidden_edges |= WLR_EDGE_BOTTOM; + } + } + + container_set_hidden_edges(con, containers_hidden_edges); + return containers_hidden_edges; +} +void container_update_border(struct container *con) +{ + // optimization to not update the border if it's not needed + container_update_border_geometry(con); + container_update_border_color(con); +} + +void container_update_border_geometry(struct container *con) +{ + container_update_border_visibility(con); + // the visibility always has to be updated because has_border might have changed + if (!con->has_border) + return; + + struct scene_surface *surface = con->client->scene_surface; + + struct wlr_box *borders = (struct wlr_box[4]) { + container_get_current_border_geom(con, WLR_EDGE_TOP), + container_get_current_border_geom(con, WLR_EDGE_BOTTOM), + container_get_current_border_geom(con, WLR_EDGE_LEFT), + container_get_current_border_geom(con, WLR_EDGE_RIGHT), + }; + + for (int i = 0; i < BORDER_COUNT; i++) { + struct wlr_scene_rect *border = surface->borders[i]; + struct wlr_box geom = borders[i]; + wlr_scene_node_set_position(&border->node, geom.x, geom.y); + wlr_scene_rect_set_size(border, geom.width, geom.height); + } +} + +void container_update_border_color(struct container *con) +{ + if (!con->has_border) + return; + struct scene_surface *surface = con->client->scene_surface; + + struct monitor *m = container_get_monitor(con); + struct tag *tag = monitor_get_active_tag(m); + struct layout *lt = tag_get_layout(tag); + + struct container *sel = monitor_get_focused_container(m); + const struct color color = (con == sel) ? lt->options->focus_color : + lt->options->border_color; + + for (int i = 0; i < BORDER_COUNT; i++) { + struct wlr_scene_rect *border = surface->borders[i]; + float border_color[4]; + color_to_wlr_color(border_color, color); + wlr_scene_rect_set_color(border, border_color); + } +} + +void container_update_border_visibility(struct container *con) +{ + struct scene_surface *surface = con->client->scene_surface; + + if (!con->has_border) { + for (int i = 0; i < BORDER_COUNT; i++) { + struct wlr_scene_rect *border = surface->borders[i]; + wlr_scene_node_set_enabled(&border->node, false); + } + return; + } + + struct monitor *m = container_get_monitor(con); + struct tag *tag = monitor_get_active_tag(m); + struct layout *lt = tag_get_layout(tag); + + struct wlr_box *borders = (struct wlr_box[4]) { + container_get_current_border_geom(con, WLR_EDGE_TOP), + container_get_current_border_geom(con, WLR_EDGE_BOTTOM), + container_get_current_border_geom(con, WLR_EDGE_LEFT), + container_get_current_border_geom(con, WLR_EDGE_RIGHT), + }; + + enum wlr_edges hidden_edges = WLR_EDGE_NONE; + if (lt->options->smart_hidden_edges) { + if (tag->visible_con_set->tiled_containers->len <= 1) { + hidden_edges = container_update_hidden_edges(con, borders, + lt->options->hidden_edges); + } + } else { + hidden_edges = container_update_hidden_edges(con, borders, + lt->options->hidden_edges); + } + + for (int i = 0; i < BORDER_COUNT; i++) { + struct wlr_scene_rect *border = surface->borders[i]; + + bool is_hidden = hidden_edges & (1 << i); + // hide or show the border + wlr_scene_node_set_enabled(&border->node, !is_hidden); + } +} + void resize_container(struct container *con, struct wlr_cursor *cursor, int offsetx, int offsety) { if (!con) diff --git a/src/render.c b/src/render.c index 45fa8dd3..59237796 100644 --- a/src/render.c +++ b/src/render.c @@ -24,98 +24,13 @@ static void surface_handle_destroy(struct wl_listener *listener, void *data) free(surface); } -// TODO refactor the name it doesn't represent what this does perfectly -// returns the newly accquired hidden edges -static enum wlr_edges container_update_hidden_edges(struct container *con, struct wlr_box *borders, enum wlr_edges hidden_edges) -{ - struct monitor *m = container_get_monitor(con); - - enum wlr_edges containers_hidden_edges = WLR_EDGE_NONE; - struct wlr_box con_geom = container_get_current_geom(con); - // int border_width = container_get_border_width(con); - // hide edges if needed - if (hidden_edges & WLR_EDGE_LEFT) { - if (con_geom.x == m->root->geom.x) { - containers_hidden_edges |= WLR_EDGE_LEFT; - } - } - if (hidden_edges & WLR_EDGE_RIGHT) { - if (is_approx_equal(con_geom.x + con_geom.width, m->root->geom.x + m->root->geom.width, 3)) { - containers_hidden_edges |= WLR_EDGE_RIGHT; - } - } - if (hidden_edges & WLR_EDGE_TOP) { - if (con_geom.y == m->root->geom.y) { - containers_hidden_edges |= WLR_EDGE_TOP; - } - } - if (hidden_edges & WLR_EDGE_BOTTOM) { - if (is_approx_equal(con_geom.y + con_geom.height, m->root->geom.y + m->root->geom.height, 3)) { - containers_hidden_edges |= WLR_EDGE_BOTTOM; - } - } - - container_set_hidden_edges(con, containers_hidden_edges); - return containers_hidden_edges; -} static void surface_handle_commit(struct wl_listener *listener, void *data) { struct scene_surface *surface = wl_container_of(listener, surface, commit); struct client *c = wlr_surface_get_client(surface->wlr); struct container *con = c->con; - struct monitor *m = container_get_monitor(con); - - if (!con->has_border) { - for (int i = 0; i < BORDER_COUNT; i++) { - struct wlr_scene_rect *border = surface->borders[i]; - wlr_scene_node_set_enabled(&border->node, false); - } - return; - } - - struct wlr_box *borders = (struct wlr_box[4]) { - container_get_current_border_geom(con, WLR_EDGE_TOP), - container_get_current_border_geom(con, WLR_EDGE_BOTTOM), - container_get_current_border_geom(con, WLR_EDGE_LEFT), - container_get_current_border_geom(con, WLR_EDGE_RIGHT), - }; - - enum wlr_edges hidden_edges = WLR_EDGE_NONE; - struct tag *tag = monitor_get_active_tag(m); - struct layout *lt = tag_get_layout(tag); - if (lt->options->smart_hidden_edges) { - if (tag->visible_con_set->tiled_containers->len <= 1) { - hidden_edges = container_update_hidden_edges(con, borders, - lt->options->hidden_edges); - } - } else { - hidden_edges = container_update_hidden_edges(con, borders, - lt->options->hidden_edges); - } - - struct container *sel = monitor_get_focused_container(m); - const struct color color = (con == sel) ? lt->options->focus_color : - lt->options->border_color; - - for (int i = 0; i < BORDER_COUNT; i++) { - struct wlr_scene_rect *border = surface->borders[i]; - struct wlr_box geom = borders[i]; - - bool is_hidden = hidden_edges & (1 << i); - // hide or show the border - wlr_scene_node_set_enabled(&border->node, !is_hidden); - if (is_hidden) { - continue; - } - - wlr_scene_node_set_position(&border->node, geom.x, geom.y); - wlr_scene_rect_set_size(border, geom.width, geom.height); - - float border_color[4]; - color_to_wlr_color(border_color, color); - wlr_scene_rect_set_color(border, border_color); - } + container_update_border_color(con); } void server_handle_new_surface(struct wl_listener *listener, void *data) diff --git a/src/tile/tileUtils.c b/src/tile/tileUtils.c index 7063116f..3c1f0761 100644 --- a/src/tile/tileUtils.c +++ b/src/tile/tileUtils.c @@ -240,6 +240,17 @@ void arrange_monitor(struct monitor *m) update_reduced_focus_stack(tag); tag_focus_most_recent_container(tag); + + // update container visibility + GPtrArray *stack_list = tag_get_complete_stack_copy(tag); + for (int i = stack_list->len-1; i >= 0; i--) { + struct container *con = g_ptr_array_index(stack_list, i); + bool viewable = container_viewable_on_monitor(m, con); + struct scene_surface *scene_surface = con->client->scene_surface; + struct wlr_scene_node *node = &scene_surface->surface_tree->node; + wlr_scene_node_set_enabled(node, viewable); + } + g_ptr_array_unref(stack_list); } void arrange_containers( @@ -334,6 +345,7 @@ void container_update_size(struct container *con) con_geom.x, con_geom.y, con_geom.width, con_geom.height); } + container_update_border_geometry(con); } void update_hidden_status_of_containers(struct monitor *m, GPtrArray *tiled_containers) From 4ba27225c607c2c9e19383ae90e6904cec8b0f83 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 15:40:45 +0200 Subject: [PATCH 21/37] fix: fix borders disappearing on float --- include/container.h | 2 ++ include/render.h | 2 ++ include/server.h | 8 ++++---- src/container.c | 16 ++++++++++++++++ src/render.c | 2 +- src/server.c | 8 ++++---- 6 files changed, 29 insertions(+), 9 deletions(-) diff --git a/include/container.h b/include/container.h index 2403938c..839b1e83 100644 --- a/include/container.h +++ b/include/container.h @@ -197,5 +197,7 @@ bool container_is_managed(struct container *con); bool container_is_tiled_and_managed(struct container *con); bool container_is_on_scratchpad(struct container *con); +struct wlr_scene_node *container_get_scene_node(struct container *con); + const char *container_get_app_id(struct container *con); #endif /* CONTAINER_H */ diff --git a/include/render.h b/include/render.h index ac876dd4..7c25a1af 100644 --- a/include/render.h +++ b/include/render.h @@ -3,6 +3,8 @@ #include +#include "container.h" + #define BORDER_COUNT 4 struct scene_surface { diff --git a/include/server.h b/include/server.h index ebb21678..0574c90b 100644 --- a/include/server.h +++ b/include/server.h @@ -47,10 +47,10 @@ struct server { struct event_handler *event_handler; struct wlr_scene *scene; - struct wlr_scene_tree *pending; - struct wlr_scene_tree *background; - struct wlr_scene_tree *foreground; - struct wlr_scene_tree *floating; + struct wlr_scene_tree *scene_background; + struct wlr_scene_tree *scene_tiled; + struct wlr_scene_tree *scene_floating; + struct wlr_scene_tree *scene_top; struct wl_listener new_surface; diff --git a/src/container.c b/src/container.c index b2a8a57b..44800ee7 100644 --- a/src/container.c +++ b/src/container.c @@ -622,6 +622,13 @@ void container_set_floating(struct container *con, void (*fix_position)(struct c if (fix_position) fix_position(con); + struct wlr_scene_node *node = container_get_scene_node(con); + if (floating) { + wlr_scene_node_reparent(node, server.scene_floating); + } else { + wlr_scene_node_reparent(node, server.scene_tiled); + } + container_property_set_floating(property, floating); } @@ -692,6 +699,8 @@ void move_container(struct container *con, struct wlr_cursor *cursor, int offset struct tag *tag = monitor_get_active_tag(m); struct layout *lt = tag_get_layout(tag); container_set_border_width(con, direction_value_uniform(lt->options->float_border_px)); + + container_update_size(con); } struct container_property *container_get_property(struct container *con) @@ -1715,3 +1724,10 @@ const char *container_get_app_id(struct container *con) } return name; } + +struct wlr_scene_node *container_get_scene_node(struct container *con) +{ + struct client *c = con->client; + struct scene_surface *surface = c->scene_surface; + return &surface->surface_tree->node; +} diff --git a/src/render.c b/src/render.c index 59237796..0961a34f 100644 --- a/src/render.c +++ b/src/render.c @@ -47,7 +47,7 @@ void server_handle_new_surface(struct wl_listener *listener, void *data) surface->destroy.notify = surface_handle_destroy; wl_signal_add(&wlr_surface->events.destroy, &surface->destroy); - surface->surface_tree = wlr_scene_tree_create(server->pending); + surface->surface_tree = wlr_scene_tree_create(server->scene_tiled); surface->scene_surface = wlr_scene_surface_create(surface->surface_tree, wlr_surface); diff --git a/src/server.c b/src/server.c index 1a3c834f..2a6ba243 100644 --- a/src/server.c +++ b/src/server.c @@ -493,10 +493,10 @@ int setup_server(struct server *server) server->scene = wlr_scene_create(); struct wlr_scene *server_scene = server->scene; - server->background = wlr_scene_tree_create(&server_scene->tree); - server->foreground = wlr_scene_tree_create(&server_scene->tree); - server->floating = wlr_scene_tree_create(&server_scene->tree); - server->pending = wlr_scene_tree_create(&server_scene->tree); + server->scene_background = wlr_scene_tree_create(&server_scene->tree); + server->scene_tiled = wlr_scene_tree_create(&server_scene->tree); + server->scene_floating = wlr_scene_tree_create(&server_scene->tree); + server->scene_top = wlr_scene_tree_create(&server_scene->tree); server->new_surface.notify = server_handle_new_surface; wl_signal_add(&server->compositor->events.new_surface, &server->new_surface); From 411d590c4c9a3f058477562b495e2a7a4c177dbd Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 16:40:10 +0200 Subject: [PATCH 22/37] fix: reparenting issues with Layer_shell clients --- include/server.h | 2 +- src/client.c | 4 ++-- src/ipc-server.c | 12 ++++++++++++ src/render.c | 1 - src/server.c | 2 +- src/tag.c | 16 ++++++++++++++++ src/tile/tileUtils.c | 4 ++-- 7 files changed, 34 insertions(+), 7 deletions(-) diff --git a/include/server.h b/include/server.h index 0574c90b..07ab441a 100644 --- a/include/server.h +++ b/include/server.h @@ -50,7 +50,7 @@ struct server { struct wlr_scene_tree *scene_background; struct wlr_scene_tree *scene_tiled; struct wlr_scene_tree *scene_floating; - struct wlr_scene_tree *scene_top; + struct wlr_scene_tree *scene_overlay; struct wl_listener new_surface; diff --git a/src/client.c b/src/client.c index 0d155c4a..ae8c0c79 100644 --- a/src/client.c +++ b/src/client.c @@ -27,8 +27,8 @@ struct client *create_client(enum shell shell_type, union surface_t surface) c->type = shell_type; c->surface = surface; - // TODO: this is a hack. first wlr_surface->data is filled with the surface - // then we will fill it with the corro + // HACK: this is a hack. first wlr_surface->data is filled with the surface + // then we will override it with the client afterwards switch (shell_type) { case XDG_SHELL: c->scene_surface = surface.xdg->surface->data; diff --git a/src/ipc-server.c b/src/ipc-server.c index 9e23a958..15ba2621 100644 --- a/src/ipc-server.c +++ b/src/ipc-server.c @@ -289,6 +289,18 @@ static void ipc_send_event(const char *json_string, enum ipc_command_type event) void ipc_event_tag() { ipc_send_event("", IPC_EVENT_TAG); + + // TODO: this doesn't belong here + // HACK: just for the time being + // update container visibility + for (int i = server.container_stack->len-1; i >= 0; i--) { + struct container *con = g_ptr_array_index(server.container_stack, i); + struct monitor *m = server_get_selected_monitor(); + bool viewable = container_viewable_on_monitor(m, con); + struct wlr_scene_node *node = container_get_scene_node(con); + printf("i: %i enable: %i\n", i, viewable); + wlr_scene_node_set_enabled(node, viewable); + } } int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { diff --git a/src/render.c b/src/render.c index 0961a34f..ebeb8c53 100644 --- a/src/render.c +++ b/src/render.c @@ -38,7 +38,6 @@ void server_handle_new_surface(struct wl_listener *listener, void *data) printf("create notify new surface\n"); struct server *server = wl_container_of(listener, server, new_surface); struct wlr_surface *wlr_surface = data; - // wlr_surface->role_data struct scene_surface *surface = calloc(1, sizeof(struct scene_surface)); surface->wlr = wlr_surface; diff --git a/src/server.c b/src/server.c index 2a6ba243..ad0590a9 100644 --- a/src/server.c +++ b/src/server.c @@ -496,7 +496,7 @@ int setup_server(struct server *server) server->scene_background = wlr_scene_tree_create(&server_scene->tree); server->scene_tiled = wlr_scene_tree_create(&server_scene->tree); server->scene_floating = wlr_scene_tree_create(&server_scene->tree); - server->scene_top = wlr_scene_tree_create(&server_scene->tree); + server->scene_overlay = wlr_scene_tree_create(&server_scene->tree); server->new_surface.notify = server_handle_new_surface; wl_signal_add(&server->compositor->events.new_surface, &server->new_surface); diff --git a/src/tag.c b/src/tag.c index 02bb95ec..ecd9bdbf 100644 --- a/src/tag.c +++ b/src/tag.c @@ -876,6 +876,22 @@ void add_container_to_layer_stack(struct container *con) con->client->layer = con->client->surface.layer->current.layer; g_ptr_array_insert(get_layer_list(con->client->layer), 0, con); + + struct wlr_scene_node *node = container_get_scene_node(con); + switch(con->client->layer) { + case ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND: + wlr_scene_node_reparent(node, server.scene_background); + break; + case ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM: + wlr_scene_node_reparent(node, server.scene_tiled); + break; + case ZWLR_LAYER_SHELL_V1_LAYER_TOP: + wlr_scene_node_reparent(node, server.scene_floating); + break; + case ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY: + wlr_scene_node_reparent(node, server.scene_overlay); + break; + } return; } diff --git a/src/tile/tileUtils.c b/src/tile/tileUtils.c index 3c1f0761..3c1bdc3d 100644 --- a/src/tile/tileUtils.c +++ b/src/tile/tileUtils.c @@ -246,8 +246,8 @@ void arrange_monitor(struct monitor *m) for (int i = stack_list->len-1; i >= 0; i--) { struct container *con = g_ptr_array_index(stack_list, i); bool viewable = container_viewable_on_monitor(m, con); - struct scene_surface *scene_surface = con->client->scene_surface; - struct wlr_scene_node *node = &scene_surface->surface_tree->node; + struct wlr_scene_node *node = container_get_scene_node(con); + printf("i: %i enable: %i\n", i, viewable); wlr_scene_node_set_enabled(node, viewable); } g_ptr_array_unref(stack_list); From d5798f01958c9769c7b62459fc839f71ea9e5430 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 19:21:39 +0200 Subject: [PATCH 23/37] fix: fix stuff --- include/popup.h | 2 ++ include/render.h | 1 + include/server.h | 1 + src/ipc-server.c | 1 - src/popup.c | 18 +++++++++++++++++- src/render.c | 15 +++++++++++++-- src/server.c | 1 + src/tile/tileUtils.c | 1 - 8 files changed, 35 insertions(+), 5 deletions(-) diff --git a/include/popup.h b/include/popup.h index f475948d..07b05b24 100644 --- a/include/popup.h +++ b/include/popup.h @@ -11,6 +11,7 @@ struct xdg_popup { struct wlr_box geom; struct monitor *m; void *parent; + struct wlr_scene_surface *scene_surface; struct wl_listener map; struct wl_listener unmap; @@ -31,4 +32,5 @@ void popup_set_x(struct xdg_popup *popup, int x); void popup_set_y(struct xdg_popup *popup, int y); void popup_set_width(struct xdg_popup *popup, int width); void popup_set_height(struct xdg_popup *popup, int height); +void pupup_update_position(struct xdg_popup *popup); #endif /* POPUP_H */ diff --git a/include/render.h b/include/render.h index 7c25a1af..40f7028c 100644 --- a/include/render.h +++ b/include/render.h @@ -16,6 +16,7 @@ struct scene_surface { struct wl_listener commit; struct wl_listener destroy; + struct wl_listener new_subsurface; }; void scene_create(struct wlr_scene **scene); diff --git a/include/server.h b/include/server.h index 07ab441a..90da426c 100644 --- a/include/server.h +++ b/include/server.h @@ -50,6 +50,7 @@ struct server { struct wlr_scene_tree *scene_background; struct wlr_scene_tree *scene_tiled; struct wlr_scene_tree *scene_floating; + struct wlr_scene_tree *scene_popups; struct wlr_scene_tree *scene_overlay; diff --git a/src/ipc-server.c b/src/ipc-server.c index 15ba2621..33b96b88 100644 --- a/src/ipc-server.c +++ b/src/ipc-server.c @@ -298,7 +298,6 @@ void ipc_event_tag() { struct monitor *m = server_get_selected_monitor(); bool viewable = container_viewable_on_monitor(m, con); struct wlr_scene_node *node = container_get_scene_node(con); - printf("i: %i enable: %i\n", i, viewable); wlr_scene_node_set_enabled(node, viewable); } } diff --git a/src/popup.c b/src/popup.c index 56f14508..fb840cd3 100644 --- a/src/popup.c +++ b/src/popup.c @@ -15,7 +15,6 @@ #include "xdg-shell-protocol.h" static void popup_handle_new_popup(struct wl_listener *listener, void *data); -static void popup_handle_new_subpopup(struct wl_listener *listener, void *data); static void destroy_popup(struct xdg_popup *xdg_popup); static void popup_handle_commit(struct wl_listener *listener, void *data); static void popup_handle_map(struct wl_listener *listener, void *data); @@ -70,6 +69,9 @@ static void popup_handle_map(struct wl_listener *listener, void *data) double sx, sy; wlr_xdg_popup_get_position(xdg_popup, &sx, &sy); + popup->scene_surface = xdg_popup->base->surface->data; + struct wlr_scene_surface *scene_surface = popup->scene_surface; + int offset_x = 0; int offset_y = 0; @@ -94,6 +96,9 @@ static void popup_handle_map(struct wl_listener *listener, void *data) popup_set_y(popup, offset_y + sy); popup_set_width(popup, xdg_popup->current.geometry.width); popup_set_height(popup, xdg_popup->current.geometry.height); + pupup_update_position(popup); + + wlr_scene_node_set_position(&scene_surface->buffer->node, sx, sy); // TODO: either use this or use actual xdg constraints struct monitor *m = server_get_selected_monitor(); @@ -116,6 +121,9 @@ static void popup_handle_new_popup(struct wl_listener *listener, void *data) wl_container_of(listener, parent_popup, new_popup); struct wlr_xdg_popup *xdg_popup = data; + struct wlr_scene_surface *scene_surface = xdg_popup->base->surface->data; + struct wlr_scene_node *node = &scene_surface->buffer->node; + wlr_scene_node_set_position(node, 0, 0); create_popup(parent_popup->m, xdg_popup, parent_popup, parent_popup->toplevel); } @@ -213,3 +221,11 @@ void popup_set_height(struct xdg_popup *popup, int height) { popup->geom.height = height; } + +void pupup_update_position(struct xdg_popup *popup) +{ + struct wlr_scene_surface *scene_surface = popup->scene_surface; + struct wlr_box geom = popup->geom; + printf("set x: %i y: %i\n", geom.x, geom.y); + wlr_scene_node_set_position(&scene_surface->buffer->node, 0, 0); +} diff --git a/src/render.c b/src/render.c index ebeb8c53..3bbe1b61 100644 --- a/src/render.c +++ b/src/render.c @@ -24,8 +24,8 @@ static void surface_handle_destroy(struct wl_listener *listener, void *data) free(surface); } - -static void surface_handle_commit(struct wl_listener *listener, void *data) { +static void surface_handle_commit(struct wl_listener *listener, void *data) +{ struct scene_surface *surface = wl_container_of(listener, surface, commit); struct client *c = wlr_surface_get_client(surface->wlr); @@ -33,6 +33,11 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) { container_update_border_color(con); } +static void surface_handle_new_subsurface(struct wl_listener *listener, void *data) +{ +} + +int i = 0; void server_handle_new_surface(struct wl_listener *listener, void *data) { printf("create notify new surface\n"); @@ -41,15 +46,21 @@ void server_handle_new_surface(struct wl_listener *listener, void *data) struct scene_surface *surface = calloc(1, sizeof(struct scene_surface)); surface->wlr = wlr_surface; + printf("wlr_surface: %p\n", wlr_surface); surface->commit.notify = surface_handle_commit; wl_signal_add(&wlr_surface->events.commit, &surface->commit); surface->destroy.notify = surface_handle_destroy; wl_signal_add(&wlr_surface->events.destroy, &surface->destroy); + surface->new_subsurface.notify = surface_handle_new_subsurface;; + wl_signal_add(&wlr_surface->events.new_subsurface, &surface->new_subsurface); + surface->surface_tree = wlr_scene_tree_create(server->scene_tiled); surface->scene_surface = wlr_scene_surface_create(surface->surface_tree, wlr_surface); + wlr_scene_node_set_position(&surface->scene_surface->buffer->node, 100, 100); + wlr_scene_node_set_position(&surface->scene_surface->buffer->node, 200, 200); for (int i = 0; i < BORDER_COUNT; i++) { surface->borders[i] = diff --git a/src/server.c b/src/server.c index ad0590a9..3cd6d97a 100644 --- a/src/server.c +++ b/src/server.c @@ -496,6 +496,7 @@ int setup_server(struct server *server) server->scene_background = wlr_scene_tree_create(&server_scene->tree); server->scene_tiled = wlr_scene_tree_create(&server_scene->tree); server->scene_floating = wlr_scene_tree_create(&server_scene->tree); + server->scene_popups = wlr_scene_tree_create(&server_scene->tree); server->scene_overlay = wlr_scene_tree_create(&server_scene->tree); server->new_surface.notify = server_handle_new_surface; diff --git a/src/tile/tileUtils.c b/src/tile/tileUtils.c index 3c1bdc3d..72c49695 100644 --- a/src/tile/tileUtils.c +++ b/src/tile/tileUtils.c @@ -247,7 +247,6 @@ void arrange_monitor(struct monitor *m) struct container *con = g_ptr_array_index(stack_list, i); bool viewable = container_viewable_on_monitor(m, con); struct wlr_scene_node *node = container_get_scene_node(con); - printf("i: %i enable: %i\n", i, viewable); wlr_scene_node_set_enabled(node, viewable); } g_ptr_array_unref(stack_list); From b1ad19277a6cf1e6707b4fe7bed3de6e5dbaaf78 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 17 Apr 2023 19:25:44 +0200 Subject: [PATCH 24/37] add todo --- src/render.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/render.c b/src/render.c index 3bbe1b61..5bd8920b 100644 --- a/src/render.c +++ b/src/render.c @@ -37,7 +37,6 @@ static void surface_handle_new_subsurface(struct wl_listener *listener, void *da { } -int i = 0; void server_handle_new_surface(struct wl_listener *listener, void *data) { printf("create notify new surface\n"); @@ -59,8 +58,9 @@ void server_handle_new_surface(struct wl_listener *listener, void *data) surface->scene_surface = wlr_scene_surface_create(surface->surface_tree, wlr_surface); - wlr_scene_node_set_position(&surface->scene_surface->buffer->node, 100, 100); - wlr_scene_node_set_position(&surface->scene_surface->buffer->node, 200, 200); + // TODO: this doesn't work for popups + // wlr_scene_node_set_position(&surface->scene_surface->buffer->node, 100, 100); + // wlr_scene_node_set_position(&surface->scene_surface->buffer->node, 200, 200); for (int i = 0; i < BORDER_COUNT; i++) { surface->borders[i] = From afa09cd2b5be0a4136146de8f76d88a16956c76a Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 11 Dec 2023 18:45:32 +0100 Subject: [PATCH 25/37] fix: upgrade xwayland code --- include/client.h | 4 ++-- include/monitor.h | 1 - include/server.h | 1 + include/utils/coreUtils.h | 4 ++++ meson.build | 2 +- src/container.c | 18 +++++++-------- src/cursor.c | 22 +++++++++---------- src/keyboard.c | 4 ++-- src/layer_shell.c | 24 +++++--------------- src/main.c | 7 ------ src/monitor.c | 15 ++----------- src/popup.c | 21 ++++++------------ src/server.c | 15 +++++++------ src/utils/coreUtils.c | 3 --- src/xdg_shell.c | 46 +++++++++++++++++++-------------------- src/xwayland.c | 15 ++++++------- 16 files changed, 82 insertions(+), 120 deletions(-) diff --git a/include/client.h b/include/client.h index 3860c309..d097bafc 100644 --- a/include/client.h +++ b/include/client.h @@ -28,8 +28,8 @@ struct client { struct wl_listener ack_configure; struct wl_listener set_title; struct wl_listener set_app_id; - struct wl_listener map; - struct wl_listener unmap; + struct wl_listener associate; + struct wl_listener dissociate; struct wl_listener destroy; struct wl_listener new_popup; struct wl_listener new_subsurface; diff --git a/include/monitor.h b/include/monitor.h index 4271ad60..8cee72e4 100644 --- a/include/monitor.h +++ b/include/monitor.h @@ -2,7 +2,6 @@ #define MONITOR_H #include #include -#include #include #include "server.h" diff --git a/include/server.h b/include/server.h index 90da426c..90a2e435 100644 --- a/include/server.h +++ b/include/server.h @@ -31,6 +31,7 @@ struct server { struct wl_display *wl_display; struct wl_event_loop *wl_event_loop; + struct wlr_session *wlr_session; struct wlr_backend *backend; struct wlr_compositor *compositor; struct wlr_renderer *renderer; diff --git a/include/utils/coreUtils.h b/include/utils/coreUtils.h index 241bb062..633dca36 100644 --- a/include/utils/coreUtils.h +++ b/include/utils/coreUtils.h @@ -42,6 +42,10 @@ typedef GPtrArray GPtrArray2D; #define MIN_CONTAINER_HEIGHT 30 #define LISTEN(E, L, H) wl_signal_add((E), ((L)->notify = (H), (L))) +// version management +#define WL_COMPOSITOR_VERSION 6 +#define LAYER_SHELL_VERSION 4 + #define foreach(item, array)\ for(int keep = 1, count = 0, size = LENGTH(array); keep && count < size; keep = 1, count++)\ for(item = array[count]; keep; keep = 0)\ diff --git a/meson.build b/meson.build index 162ded77..1faa36ee 100644 --- a/meson.build +++ b/meson.build @@ -163,7 +163,7 @@ deps = [\ wayland_client, wayland_protos, dependency('pixman-1'), - dependency('wlroots', version: ['>=0.15' ,'<0.17']), + dependency('wlroots', version: ['>=0.15' ,'<0.18']), dependency('x11'), dependency('json-c'), dependency('libnotify'), diff --git a/src/container.c b/src/container.c index 44800ee7..c38c7ce3 100644 --- a/src/container.c +++ b/src/container.c @@ -11,7 +11,6 @@ #include "cursor.h" #include "list_sets/container_stack_set.h" #include "list_sets/list_set.h" -#include "popup.h" #include "server.h" #include "monitor.h" #include "tile/tileUtils.h" @@ -22,7 +21,6 @@ #include "ipc-server.h" #include "layer_shell.h" #include "tag.h" -#include "rules/rule.h" #include "list_sets/focus_stack_set.h" #include "options.h" #include "lib/lib_container.h" @@ -1561,22 +1559,22 @@ void container_resize_with_cursor(struct cursor *cursor) switch (edge) { case WLR_EDGE_LEFT: printf("left\n"); - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_mgr, - "left_side", wlr_cursor); + wlr_cursor_set_xcursor(wlr_cursor, + cursor->xcursor_mgr, "left_side"); break; case WLR_EDGE_RIGHT: printf("right\n"); - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_mgr, - "right_side", wlr_cursor); + wlr_cursor_set_xcursor(wlr_cursor, + cursor->xcursor_mgr, "right_side"); break; case WLR_EDGE_TOP: printf("top\n"); - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_mgr, - "top_side", wlr_cursor); + wlr_cursor_set_xcursor(wlr_cursor, + cursor->xcursor_mgr, "top_side"); break; case WLR_EDGE_BOTTOM: - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_mgr, - "bottom_side", wlr_cursor); + wlr_cursor_set_xcursor(wlr_cursor, + cursor->xcursor_mgr, "bottom_side"); break; default: break; diff --git a/src/cursor.c b/src/cursor.c index 71faa4ac..7438a2c4 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -98,7 +98,7 @@ static void handle_image_surface_destroy(struct wl_listener *listener, } static void cursor_hide(struct cursor *cursor) { - wlr_cursor_set_image(cursor->wlr_cursor, NULL, 0, 0, 0, 0, 0, 0); + wlr_cursor_set_buffer(cursor->wlr_cursor, NULL, 0, 0, 0); cursor->hidden = true; wlr_seat_pointer_notify_clear_focus(cursor->seat->wlr_seat); } @@ -215,10 +215,10 @@ void cursor_set_image(struct cursor *cursor, const char *image, struct wl_client } if (!image) { - wlr_cursor_set_image(cursor->wlr_cursor, NULL, 0, 0, 0, 0, 0, 0); + wlr_cursor_set_buffer(cursor->wlr_cursor, NULL, 0, 0, 0); } else if (!current_image || strcmp(current_image, image) != 0) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_mgr, image, - cursor->wlr_cursor); + wlr_cursor_set_xcursor(cursor->wlr_cursor, cursor->xcursor_mgr, + image); } } @@ -424,8 +424,8 @@ void handle_cursor_button(struct wl_listener *listener, void *data) * mode. */ /* XXX should reset to the pointer focus's current setcursor */ if (cursor->cursor_mode != CURSOR_NORMAL) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_mgr, - "left_ptr", cursor->wlr_cursor); + wlr_cursor_set_xcursor(cursor->wlr_cursor, + cursor->xcursor_mgr, "left_ptr"); cursor->cursor_mode = CURSOR_NORMAL; /* Drop the window off on its new monitor */ struct monitor *m = xy_to_monitor(cursor->wlr_cursor->x, @@ -476,7 +476,7 @@ void move_resize(struct cursor *cursor, int ui) struct wlr_cursor *wlr_cursor = cursor->wlr_cursor; switch (cursor->cursor_mode = ui) { case CURSOR_MOVE: - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_mgr, "fleur", wlr_cursor); + wlr_cursor_set_xcursor(wlr_cursor, cursor->xcursor_mgr, "fleur"); offsetx = absolute_x_to_container_local(grabc_geom, wlr_cursor->x); offsety = absolute_y_to_container_local(grabc_geom, wlr_cursor->y); break; @@ -486,8 +486,8 @@ void move_resize(struct cursor *cursor, int ui) wlr_cursor_warp_closest(wlr_cursor, NULL, grabc_geom.x + grabc_geom.width, grabc_geom.y + grabc_geom.height); - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_mgr, - "bottom_right_corner", wlr_cursor); + wlr_cursor_set_xcursor(wlr_cursor, + cursor->xcursor_mgr, "bottom_right_corner"); break; default: break; @@ -713,8 +713,8 @@ static void update_cursor(struct cursor *cursor) return; if (!xy_to_container(cursor->wlr_cursor->x, cursor->wlr_cursor->y)) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_mgr, - "left_ptr", cursor->wlr_cursor); + wlr_cursor_set_xcursor(cursor->wlr_cursor, + cursor->xcursor_mgr, "left_ptr"); return; } diff --git a/src/keyboard.c b/src/keyboard.c index 9e03ab9a..884cbed1 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -4,6 +4,7 @@ #include "server.h" #include "keybinding.h" #include "utils/coreUtils.h" +#include static bool handle_VT_keys(struct keyboard *kb, uint32_t keycode) { @@ -18,8 +19,7 @@ static bool handle_VT_keys(struct keyboard *kb, uint32_t keycode) break; /* if required switch to different virtual terminal */ - struct wlr_session *session = - wlr_backend_get_session(server.backend); + struct wlr_session *session = server.wlr_session; if (!session) break; diff --git a/src/layer_shell.c b/src/layer_shell.c index 217bc41f..ba7acd74 100644 --- a/src/layer_shell.c +++ b/src/layer_shell.c @@ -5,7 +5,6 @@ #include #include "monitor.h" -#include "popup.h" #include "server.h" #include "container.h" #include "tile/tileUtils.h" @@ -28,8 +27,6 @@ void create_notify_layer_shell(struct wl_listener *listener, void *data) struct client *client = create_client(LAYER_SHELL, surface); LISTEN(&wlr_layer_surface->surface->events.commit, &client->commit, commit_layer_surface_notify); - LISTEN(&wlr_layer_surface->events.map, &client->map, map_layer_surface_notify); - LISTEN(&wlr_layer_surface->events.unmap, &client->unmap, unmap_layer_surface_notify); LISTEN(&wlr_layer_surface->events.destroy, &client->destroy, destroy_layer_surface_notify); LISTEN(&wlr_layer_surface->events.new_popup, &client->new_popup, client_handle_new_popup); LISTEN(&wlr_layer_surface->surface->events.new_subsurface, &client->new_subsurface, handle_new_subsurface); @@ -47,16 +44,11 @@ void create_notify_layer_shell(struct wl_listener *listener, void *data) wlr_layer_surface->current = old_state; } -void map_layer_surface_notify(struct wl_listener *listener, void *data) -{ -} - void unmap_layer_surface(struct client *c) { struct container *con = c->con; struct tag *tag = server_get_selected_tag(); struct container *sel_con = tag_get_focused_container(tag); - c->surface.layer->mapped = 0; if (con == sel_con) { tag_this_focus_container(sel_con); } @@ -64,23 +56,19 @@ void unmap_layer_surface(struct client *c) void unmap_layer_surface_notify(struct wl_listener *listener, void *data) { - struct client *c = wl_container_of(listener, c, unmap); - unmap_layer_surface(c); } void destroy_layer_surface_notify(struct wl_listener *listener, void *data) { struct client *c = wl_container_of(listener, c, destroy); - if (c->surface.layer->mapped) - unmap_layer_surface(c); remove_in_composed_list(server.layer_visual_stack_lists, cmp_ptr, c->con); arrange_layers(c->m); wl_list_remove(&c->destroy.link); - wl_list_remove(&c->map.link); - wl_list_remove(&c->unmap.link); + wl_list_remove(&c->associate.link); + wl_list_remove(&c->dissociate.link); wl_list_remove(&c->new_popup.link); wl_list_remove(&c->commit.link); @@ -92,6 +80,8 @@ void destroy_layer_surface_notify(struct wl_listener *listener, void *data) destroy_container(c->con); destroy_client(c); + + unmap_layer_surface(c); } void commit_layer_surface_notify(struct wl_listener *listener, void *data) @@ -106,14 +96,12 @@ void commit_layer_surface_notify(struct wl_listener *listener, void *data) struct container *con = c->con; struct wlr_layer_surface_v1 *layer_surface = c->surface.layer; bool layer_changed = false; - if (layer_surface->current.committed != 0 || - c->mapped != layer_surface->mapped) { + if (layer_surface->current.committed != 0) { layer_changed = c->layer != layer_surface->current.layer; if (layer_changed) { remove_in_composed_list(server.layer_visual_stack_lists, cmp_ptr, con); add_container_to_layer_stack(con); } - c->mapped = layer_surface->mapped; arrange_layers(c->m); } } @@ -188,7 +176,7 @@ void arrange_layers(struct monitor *m) struct container *con = g_ptr_array_index(layer_list, j); struct client *c = con->client; struct wlr_layer_surface_v1 *layer_surface = c->surface.layer; - if (layer_surface->current.keyboard_interactive && layer_surface->mapped) { + if (layer_surface->current.keyboard_interactive) { // Deactivate the focused client. // TODO fix this NULL is not supported in focus_container tag_this_focus_container(con); diff --git a/src/main.c b/src/main.c index 27eb2e74..8b15db5c 100644 --- a/src/main.c +++ b/src/main.c @@ -13,19 +13,12 @@ #include #include #include -#include #include #include #include #include -#include "keyboard.h" -#include "layer_shell.h" -#include "scratchpad.h" #include "server.h" -#include "translationLayer.h" -#include "utils/parseConfigUtils.h" -#include "xdg_shell.h" #include "stringop.h" void print_help() diff --git a/src/monitor.c b/src/monitor.c index ca81c1e5..32798b7e 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -2,14 +2,12 @@ #include #include #include -#include #include #include #include #include #include -#include "ipc-server.h" #include "server.h" #include "tile/tileUtils.h" #include "tag.h" @@ -58,8 +56,6 @@ void create_monitor(struct wl_listener *listener, void *data) /* Set up event listeners */ m->destroy.notify = handle_destroy_monitor; wl_signal_add(&output->events.destroy, &m->destroy); - m->mode.notify = handle_output_mode; - wl_signal_add(&output->events.mode, &m->mode); bool is_first_monitor = server.mons->len == 0; g_ptr_array_add(server.mons, m); @@ -145,7 +141,7 @@ static void handle_output_frame(struct wl_listener *listener, void *data) { struct monitor *m = wl_container_of(listener, m, frame); - if (!wlr_scene_output_commit(m->scene_output)) { + if (!wlr_scene_output_commit(m->scene_output, NULL)) { return; } @@ -155,13 +151,6 @@ static void handle_output_frame(struct wl_listener *listener, void *data) /* NOOP */ } -static void handle_output_mode(struct wl_listener *listener, void *data) -{ - struct monitor *m = wl_container_of(listener, m, mode); - wlr_output_layout_get_box(server.output_layout, m->wlr_output, &m->geom); - arrange_layers(m); -} - static void monitor_get_initial_tag(struct monitor *m, GList *tags) { struct tag *tag = find_next_unoccupied_tag(tags, get_tag(0)); @@ -488,7 +477,7 @@ static void prepare_output( config_head->state.custom_mode.height, config_head->state.custom_mode.refresh); - wlr_output_layout_move(server.output_layout, wlr_output, + wlr_output_layout_add(server.output_layout, wlr_output, config_head->state.x, config_head->state.y); wlr_output_set_transform(wlr_output, config_head->state.transform); wlr_output_set_scale(wlr_output, config_head->state.scale); diff --git a/src/popup.c b/src/popup.c index fb840cd3..d34baaf2 100644 --- a/src/popup.c +++ b/src/popup.c @@ -9,7 +9,6 @@ #include "client.h" #include "container.h" #include "monitor.h" -#include "root.h" #include "server.h" #include "utils/coreUtils.h" #include "xdg-shell-protocol.h" @@ -17,8 +16,7 @@ static void popup_handle_new_popup(struct wl_listener *listener, void *data); static void destroy_popup(struct xdg_popup *xdg_popup); static void popup_handle_commit(struct wl_listener *listener, void *data); -static void popup_handle_map(struct wl_listener *listener, void *data); -static void popup_handle_unmap(struct wl_listener *listener, void *data); +static void popup_handle_map(struct xdg_popup *popup); struct xdg_popup *create_popup(struct monitor *m, struct wlr_xdg_popup *xdg_popup, void *parent, struct container* toplevel) @@ -35,8 +33,6 @@ struct xdg_popup *create_popup(struct monitor *m, struct wlr_xdg_popup *xdg_popu // the root window may be resized. This must be adjusted popup->m = m; - LISTEN(&popup->xdg->base->events.map, &popup->map, popup_handle_map); - LISTEN(&popup->xdg->base->events.unmap, &popup->unmap, popup_handle_unmap); LISTEN(&popup->xdg->base->events.new_popup, &popup->new_popup, popup_handle_new_popup); LISTEN(&popup->xdg->base->events.destroy, &popup->destroy, popup_handle_destroy); @@ -60,10 +56,8 @@ static void popup_handle_commit(struct wl_listener *listener, void *data) struct xdg_popup *popup = wl_container_of(listener, popup, commit); } -static void popup_handle_map(struct wl_listener *listener, void *data) +static void popup_handle_map(struct xdg_popup *popup) { - struct xdg_popup *popup = wl_container_of(listener, popup, map); - struct wlr_xdg_popup *xdg_popup = popup->xdg; double sx, sy; @@ -109,18 +103,14 @@ static void popup_handle_map(struct wl_listener *listener, void *data) wl_signal_add(&popup->xdg->base->surface->events.commit, &popup->commit); } -static void popup_handle_unmap(struct wl_listener *listener, void *data) -{ - struct xdg_popup *popup = wl_container_of(listener, popup, unmap); - wl_list_remove(&popup->commit.link); -} - static void popup_handle_new_popup(struct wl_listener *listener, void *data) { struct xdg_popup *parent_popup = wl_container_of(listener, parent_popup, new_popup); struct wlr_xdg_popup *xdg_popup = data; + popup_handle_map(parent_popup); + struct wlr_scene_surface *scene_surface = xdg_popup->base->surface->data; struct wlr_scene_node *node = &scene_surface->buffer->node; wlr_scene_node_set_position(node, 0, 0); @@ -131,6 +121,9 @@ static void popup_handle_new_popup(struct wl_listener *listener, void *data) void popup_handle_destroy(struct wl_listener *listener, void *data) { struct xdg_popup *popup = wl_container_of(listener, popup, destroy); + + wl_list_remove(&popup->commit.link); + list_remove(server.popups, cmp_ptr, popup); destroy_popup(popup); diff --git a/src/server.c b/src/server.c index 3cd6d97a..df8e7e21 100644 --- a/src/server.c +++ b/src/server.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -170,7 +169,7 @@ static int init_backend(struct server *server) { * backend based on the current environment, such as opening an X11 window * if an X11 server is running. The NULL argument here optionally allows you * to pass in a custom renderer if wlr_renderer doesnt). */ - if (!(server->backend = wlr_backend_autocreate(server->wl_display))) { + if (!(server->backend = wlr_backend_autocreate(server->wl_display, &server->wlr_session))) { printf("couldn't create backend\n"); return EXIT_FAILURE; } @@ -194,7 +193,7 @@ static void init_event_handlers(struct server *server) { LISTEN(&server->xdg_shell->events.new_surface, &server->new_xdg_surface, create_notify_xdg); - server->layer_shell = wlr_layer_shell_v1_create(server->wl_display); + server->layer_shell = wlr_layer_shell_v1_create(server->wl_display, LAYER_SHELL_VERSION); LISTEN(&server->layer_shell->events.new_surface, &server->new_layer_shell_surface, create_notify_layer_shell); @@ -359,8 +358,8 @@ static void run(char *startup_cmd) { * monitor when displayed here */ wlr_cursor_warp_closest(seat->cursor->wlr_cursor, NULL, cursor->wlr_cursor->x, cursor->wlr_cursor->y); - wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_mgr, "left_ptr", - cursor->wlr_cursor); + wlr_cursor_set_xcursor(cursor->wlr_cursor, seat->cursor->xcursor_mgr, + "left_ptr"); if (startup_cmd) { startup_pid = fork(); @@ -433,8 +432,9 @@ int setup_server(struct server *server) * to dig your fingers in and play with their behavior if you want. Note that * the clients cannot set the selection directly without compositor approval, * see the setsel() function. */ + server->compositor = - wlr_compositor_create(server->wl_display, server->renderer); + wlr_compositor_create(server->wl_display, WL_COMPOSITOR_VERSION, server->renderer); wlr_subcompositor_create(server->wl_display); @@ -445,7 +445,8 @@ int setup_server(struct server *server) wlr_gamma_control_manager_v1_create(server->wl_display); wlr_primary_selection_v1_device_manager_create(server->wl_display); wlr_viewporter_create(server->wl_display); - wlr_idle_create(server->wl_display); + // TODO: do we still need that? + // wlr_idle_create(server->wl_display); wlr_idle_inhibit_v1_create(server->wl_display); wlr_xdg_output_manager_v1_create(server->wl_display, server->output_layout); diff --git a/src/utils/coreUtils.c b/src/utils/coreUtils.c index 68bdf904..aaec9401 100644 --- a/src/utils/coreUtils.c +++ b/src/utils/coreUtils.c @@ -1,6 +1,5 @@ #include "utils/coreUtils.h" -#include #include #include #include @@ -9,11 +8,9 @@ #include #include #include -#include #include #include -#include "utils/parseConfigUtils.h" #include "ring_buffer.h" struct lua_State *L; diff --git a/src/xdg_shell.c b/src/xdg_shell.c index 8683557f..0b0e8fa6 100644 --- a/src/xdg_shell.c +++ b/src/xdg_shell.c @@ -6,13 +6,11 @@ #include "client.h" #include "monitor.h" -#include "popup.h" #include "server.h" #include "utils/coreUtils.h" #include "container.h" #include "tile/tileUtils.h" #include "tag.h" -#include "rules/rule.h" #include "subsurface.h" static void destroyxdeco(struct wl_listener *listener, void *data); @@ -56,11 +54,11 @@ void create_notify_xdg(struct wl_listener *listener, void *data) WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); /* Listen to the various events it can emit */ - LISTEN(&xdg_surface->events.map, &c->map, map_request); + LISTEN(&xdg_surface->surface->events.map, &c->associate, map_request); LISTEN(&xdg_surface->surface->events.commit, &c->commit, commit_notify); LISTEN(&xdg_surface->events.configure, &c->configure, configure_notify); LISTEN(&xdg_surface->events.ack_configure, &c->ack_configure, ack_configure); - LISTEN(&xdg_surface->events.unmap, &c->unmap, unmap_notify); + LISTEN(&xdg_surface->surface->events.unmap, &c->dissociate, unmap_notify); LISTEN(&xdg_surface->events.destroy, &c->destroy, destroy_notify); LISTEN(&xdg_surface->surface->events.new_subsurface, &c->new_subsurface, handle_new_subsurface); @@ -74,29 +72,30 @@ void create_notify_xdg(struct wl_listener *listener, void *data) void destroy_notify(struct wl_listener *listener, void *data) { - struct client *c = wl_container_of(listener, c, destroy); - - wl_list_remove(&c->map.link); - wl_list_remove(&c->commit.link); - wl_list_remove(&c->configure.link); - wl_list_remove(&c->ack_configure.link); - wl_list_remove(&c->unmap.link); - wl_list_remove(&c->destroy.link); - wl_list_remove(&c->new_subsurface.link); - - wl_list_remove(&c->set_title.link); - wl_list_remove(&c->set_app_id.link); - - wl_list_remove(&c->new_popup.link); - - destroy_container(c->con); - destroy_client(c); + // printf("DESTROY\n"); + // struct client *c = wl_container_of(listener, c, destroy); + // + // wl_list_remove(&c->map.link); + // wl_list_remove(&c->commit.link); + // wl_list_remove(&c->configure.link); + // wl_list_remove(&c->ack_configure.link); + // wl_list_remove(&c->unmap.link); + // wl_list_remove(&c->destroy.link); + // wl_list_remove(&c->new_subsurface.link); + // + // wl_list_remove(&c->set_title.link); + // wl_list_remove(&c->set_app_id.link); + // + // wl_list_remove(&c->new_popup.link); + // + // destroy_container(c->con); + // destroy_client(c); } void map_request(struct wl_listener *listener, void *data) { /* Called when the surface is mapped, or ready to display on-screen. */ - struct client *c = wl_container_of(listener, c, map); + struct client *c = wl_container_of(listener, c, associate); struct container *con = c->con; struct tag *tag = get_tag(con->tag_id); @@ -107,8 +106,9 @@ void map_request(struct wl_listener *listener, void *data) void unmap_notify(struct wl_listener *listener, void *data) { + printf("Unmap\n"); /* Called when the surface is unmapped, and should no longer be shown. */ - struct client *c = wl_container_of(listener, c, unmap); + struct client *c = wl_container_of(listener, c, dissociate); struct container *con = c->con; remove_container_from_tile(con); diff --git a/src/xwayland.c b/src/xwayland.c index 5712d4ac..441c9d21 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -50,8 +50,8 @@ void create_notifyx11(struct wl_listener *listener, void *data) // set default value will be overriden on maprequest /* Listen to the various events it can emit */ - LISTEN(&xwayland_surface->events.map, &c->map, maprequestx11); - LISTEN(&xwayland_surface->events.unmap, &c->unmap, unmap_notifyx11); + LISTEN(&xwayland_surface->events.associate, &c->associate, maprequestx11); + LISTEN(&xwayland_surface->events.dissociate, &c->dissociate, unmap_notifyx11); LISTEN(&xwayland_surface->events.destroy, &c->destroy, destroy_notifyx11); LISTEN(&xwayland_surface->events.set_title, &c->set_title, client_handle_set_title); LISTEN(&xwayland_surface->events.set_class, &c->set_app_id, client_handle_set_app_id); @@ -71,8 +71,8 @@ void destroy_notifyx11(struct wl_listener *listener, void *data) } destroy_container(c->con); - wl_list_remove(&c->map.link); - wl_list_remove(&c->unmap.link); + wl_list_remove(&c->associate.link); + wl_list_remove(&c->dissociate.link); wl_list_remove(&c->destroy.link); wl_list_remove(&c->set_title.link); wl_list_remove(&c->set_app_id.link); @@ -124,7 +124,7 @@ void handle_xwayland_ready(struct wl_listener *listener, void *data) void unmap_notifyx11(struct wl_listener *listener, void *data) { /* Called when the surface is unmapped, and should no longer be shown. */ - struct client *c = wl_container_of(listener, c, unmap); + struct client *c = wl_container_of(listener, c, dissociate); wl_list_remove(&c->commit.link); @@ -138,7 +138,7 @@ void unmap_notifyx11(struct wl_listener *listener, void *data) void maprequestx11(struct wl_listener *listener, void *data) { /* Called when the surface is mapped, or ready to display on-screen. */ - struct client *c = wl_container_of(listener, c, map); + struct client *c = wl_container_of(listener, c, associate); struct wlr_xwayland_surface *xwayland_surface = c->surface.xwayland; struct monitor *m = server_get_selected_monitor(); @@ -226,8 +226,7 @@ void maprequestx11(struct wl_listener *listener, void *data) struct container *sel = monitor_get_focused_container(m); tag_this_focus_container(sel); struct seat *seat = input_manager_get_default_seat(); - wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_mgr, - "left_ptr", seat->cursor->wlr_cursor); + wlr_cursor_set_xcursor(seat->cursor->wlr_cursor, seat->cursor->xcursor_mgr, "left_ptr"); } bool xwayland_popups_exist() From 0f33fe33989b458345a10d800b027eb9d0028ddd Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 11 Dec 2023 19:03:23 +0100 Subject: [PATCH 26/37] fix stuff --- include/client.h | 2 ++ src/layer_shell.c | 23 +++++++++++++++++------ src/xdg_shell.c | 44 +++++++++++++++++++++----------------------- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/include/client.h b/include/client.h index d097bafc..ff086b5e 100644 --- a/include/client.h +++ b/include/client.h @@ -28,6 +28,8 @@ struct client { struct wl_listener ack_configure; struct wl_listener set_title; struct wl_listener set_app_id; + struct wl_listener map; + struct wl_listener unmap; struct wl_listener associate; struct wl_listener dissociate; struct wl_listener destroy; diff --git a/src/layer_shell.c b/src/layer_shell.c index ba7acd74..ccbcdcfc 100644 --- a/src/layer_shell.c +++ b/src/layer_shell.c @@ -27,6 +27,8 @@ void create_notify_layer_shell(struct wl_listener *listener, void *data) struct client *client = create_client(LAYER_SHELL, surface); LISTEN(&wlr_layer_surface->surface->events.commit, &client->commit, commit_layer_surface_notify); + LISTEN(&wlr_layer_surface->surface->events.map, &client->map, map_layer_surface_notify); + LISTEN(&wlr_layer_surface->surface->events.unmap, &client->unmap, unmap_layer_surface_notify); LISTEN(&wlr_layer_surface->events.destroy, &client->destroy, destroy_layer_surface_notify); LISTEN(&wlr_layer_surface->events.new_popup, &client->new_popup, client_handle_new_popup); LISTEN(&wlr_layer_surface->surface->events.new_subsurface, &client->new_subsurface, handle_new_subsurface); @@ -44,11 +46,16 @@ void create_notify_layer_shell(struct wl_listener *listener, void *data) wlr_layer_surface->current = old_state; } +void map_layer_surface_notify(struct wl_listener *listener, void *data) +{ +} + void unmap_layer_surface(struct client *c) { struct container *con = c->con; struct tag *tag = server_get_selected_tag(); struct container *sel_con = tag_get_focused_container(tag); + c->surface.layer->surface->mapped = 0; if (con == sel_con) { tag_this_focus_container(sel_con); } @@ -56,19 +63,23 @@ void unmap_layer_surface(struct client *c) void unmap_layer_surface_notify(struct wl_listener *listener, void *data) { + struct client *c = wl_container_of(listener, c, unmap); + unmap_layer_surface(c); } void destroy_layer_surface_notify(struct wl_listener *listener, void *data) { struct client *c = wl_container_of(listener, c, destroy); + if (c->surface.layer->surface->mapped) + unmap_layer_surface(c); remove_in_composed_list(server.layer_visual_stack_lists, cmp_ptr, c->con); arrange_layers(c->m); wl_list_remove(&c->destroy.link); - wl_list_remove(&c->associate.link); - wl_list_remove(&c->dissociate.link); + wl_list_remove(&c->map.link); + wl_list_remove(&c->unmap.link); wl_list_remove(&c->new_popup.link); wl_list_remove(&c->commit.link); @@ -80,8 +91,6 @@ void destroy_layer_surface_notify(struct wl_listener *listener, void *data) destroy_container(c->con); destroy_client(c); - - unmap_layer_surface(c); } void commit_layer_surface_notify(struct wl_listener *listener, void *data) @@ -96,12 +105,14 @@ void commit_layer_surface_notify(struct wl_listener *listener, void *data) struct container *con = c->con; struct wlr_layer_surface_v1 *layer_surface = c->surface.layer; bool layer_changed = false; - if (layer_surface->current.committed != 0) { + if (layer_surface->current.committed != 0 || + c->mapped != layer_surface->surface->mapped) { layer_changed = c->layer != layer_surface->current.layer; if (layer_changed) { remove_in_composed_list(server.layer_visual_stack_lists, cmp_ptr, con); add_container_to_layer_stack(con); } + c->mapped = layer_surface->surface->mapped; arrange_layers(c->m); } } @@ -176,7 +187,7 @@ void arrange_layers(struct monitor *m) struct container *con = g_ptr_array_index(layer_list, j); struct client *c = con->client; struct wlr_layer_surface_v1 *layer_surface = c->surface.layer; - if (layer_surface->current.keyboard_interactive) { + if (layer_surface->current.keyboard_interactive && layer_surface->surface->mapped) { // Deactivate the focused client. // TODO fix this NULL is not supported in focus_container tag_this_focus_container(con); diff --git a/src/xdg_shell.c b/src/xdg_shell.c index 0b0e8fa6..48290e87 100644 --- a/src/xdg_shell.c +++ b/src/xdg_shell.c @@ -54,11 +54,11 @@ void create_notify_xdg(struct wl_listener *listener, void *data) WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); /* Listen to the various events it can emit */ - LISTEN(&xdg_surface->surface->events.map, &c->associate, map_request); + LISTEN(&xdg_surface->surface->events.map, &c->map, map_request); LISTEN(&xdg_surface->surface->events.commit, &c->commit, commit_notify); LISTEN(&xdg_surface->events.configure, &c->configure, configure_notify); LISTEN(&xdg_surface->events.ack_configure, &c->ack_configure, ack_configure); - LISTEN(&xdg_surface->surface->events.unmap, &c->dissociate, unmap_notify); + LISTEN(&xdg_surface->surface->events.unmap, &c->unmap, unmap_notify); LISTEN(&xdg_surface->events.destroy, &c->destroy, destroy_notify); LISTEN(&xdg_surface->surface->events.new_subsurface, &c->new_subsurface, handle_new_subsurface); @@ -72,30 +72,29 @@ void create_notify_xdg(struct wl_listener *listener, void *data) void destroy_notify(struct wl_listener *listener, void *data) { - // printf("DESTROY\n"); - // struct client *c = wl_container_of(listener, c, destroy); - // - // wl_list_remove(&c->map.link); - // wl_list_remove(&c->commit.link); - // wl_list_remove(&c->configure.link); - // wl_list_remove(&c->ack_configure.link); - // wl_list_remove(&c->unmap.link); - // wl_list_remove(&c->destroy.link); - // wl_list_remove(&c->new_subsurface.link); - // - // wl_list_remove(&c->set_title.link); - // wl_list_remove(&c->set_app_id.link); - // - // wl_list_remove(&c->new_popup.link); - // - // destroy_container(c->con); - // destroy_client(c); + struct client *c = wl_container_of(listener, c, destroy); + + wl_list_remove(&c->map.link); + wl_list_remove(&c->commit.link); + wl_list_remove(&c->configure.link); + wl_list_remove(&c->ack_configure.link); + wl_list_remove(&c->unmap.link); + wl_list_remove(&c->destroy.link); + wl_list_remove(&c->new_subsurface.link); + + wl_list_remove(&c->set_title.link); + wl_list_remove(&c->set_app_id.link); + + wl_list_remove(&c->new_popup.link); + + destroy_container(c->con); + destroy_client(c); } void map_request(struct wl_listener *listener, void *data) { /* Called when the surface is mapped, or ready to display on-screen. */ - struct client *c = wl_container_of(listener, c, associate); + struct client *c = wl_container_of(listener, c, map); struct container *con = c->con; struct tag *tag = get_tag(con->tag_id); @@ -106,9 +105,8 @@ void map_request(struct wl_listener *listener, void *data) void unmap_notify(struct wl_listener *listener, void *data) { - printf("Unmap\n"); /* Called when the surface is unmapped, and should no longer be shown. */ - struct client *c = wl_container_of(listener, c, dissociate); + struct client *c = wl_container_of(listener, c, unmap); struct container *con = c->con; remove_container_from_tile(con); From 0001d7fe3f0c7d7f5de12c1e4432000981986a82 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Mon, 11 Dec 2023 19:08:56 +0100 Subject: [PATCH 27/37] fix: random crash, on exiting window manager --- include/monitor.h | 1 - src/monitor.c | 1 - 2 files changed, 2 deletions(-) diff --git a/include/monitor.h b/include/monitor.h index 8cee72e4..ce7e50af 100644 --- a/include/monitor.h +++ b/include/monitor.h @@ -13,7 +13,6 @@ struct monitor { struct wlr_output *wlr_output; struct wlr_output_damage *damage; - struct wl_listener mode; struct wl_listener frame; struct wl_listener damage_frame; struct wl_listener destroy; diff --git a/src/monitor.c b/src/monitor.c index 32798b7e..90d25715 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -169,7 +169,6 @@ void handle_destroy_monitor(struct wl_listener *listener, void *data) { struct monitor *m = wl_container_of(listener, m, destroy); - wl_list_remove(&m->mode.link); wl_list_remove(&m->frame.link); wl_list_remove(&m->destroy.link); From f583f3e47314e8152cd66260bc4d6559340215cf Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Sun, 31 Dec 2023 14:49:20 +0100 Subject: [PATCH 28/37] refactor: refactor various functions --- src/ipc-server.c | 1 - src/layer_shell.c | 4 + src/render.c | 1 - src/server.c | 828 +++++++++++++++++++++++----------------------- 4 files changed, 424 insertions(+), 410 deletions(-) diff --git a/src/ipc-server.c b/src/ipc-server.c index 33b96b88..6b63c842 100644 --- a/src/ipc-server.c +++ b/src/ipc-server.c @@ -25,7 +25,6 @@ #include "client.h" #include "command.h" #include "monitor.h" -#include "root.h" static int ipc_socket = -1; static struct sockaddr_un *ipc_sockaddr = NULL; diff --git a/src/layer_shell.c b/src/layer_shell.c index ccbcdcfc..3c858c53 100644 --- a/src/layer_shell.c +++ b/src/layer_shell.c @@ -17,6 +17,10 @@ void create_notify_layer_shell(struct wl_listener *listener, void *data) { struct wlr_layer_surface_v1 *wlr_layer_surface = data; + printf("create layershell\n"); + printf("create layershell\n"); + printf("create layershell\n"); + printf("create layershell\n"); if (!wlr_layer_surface->output) { struct monitor *m = server_get_selected_monitor(); wlr_layer_surface->output = m->wlr_output; diff --git a/src/render.c b/src/render.c index 5bd8920b..4661aecb 100644 --- a/src/render.c +++ b/src/render.c @@ -39,7 +39,6 @@ static void surface_handle_new_subsurface(struct wl_listener *listener, void *da void server_handle_new_surface(struct wl_listener *listener, void *data) { - printf("create notify new surface\n"); struct server *server = wl_container_of(listener, server, new_surface); struct wlr_surface *wlr_surface = data; diff --git a/src/server.c b/src/server.c index df8e7e21..e9b892dc 100644 --- a/src/server.c +++ b/src/server.c @@ -55,562 +55,574 @@ static void finalize_lua_api(struct server *server); static struct tag *handle_too_few_tags(uint32_t tag_id); static struct tag *handle_too_few_tags(uint32_t tag_id) { - // no number has more than 11 digits when int is 32 bit long - char name[12]; - // TODO explain why +1 - snprintf(name, 12, "%d:%d", tag_id, c_idx_to_lua_idx(tag_id)); - - struct tag *new_tag = create_tag(name, tag_id, server.default_layout); - int *tag_id_ptr = malloc(sizeof(*tag_id_ptr)); - *tag_id_ptr = tag_id; - g_hash_table_insert(server.tags, tag_id_ptr, new_tag); - struct tag *tag = get_tag(0); - wlr_list_cat(new_tag->con_set->tiled_containers, - tag->con_set->tiled_containers); - - wlr_list_cat(new_tag->focus_set->focus_stack_layer_background, - tag->focus_set->focus_stack_layer_background); - wlr_list_cat(new_tag->focus_set->focus_stack_layer_bottom, - tag->focus_set->focus_stack_layer_bottom); - wlr_list_cat(new_tag->focus_set->focus_stack_layer_top, - tag->focus_set->focus_stack_layer_top); - wlr_list_cat(new_tag->focus_set->focus_stack_layer_overlay, - tag->focus_set->focus_stack_layer_overlay); - wlr_list_cat(new_tag->focus_set->focus_stack_on_top, - tag->focus_set->focus_stack_on_top); - wlr_list_cat(new_tag->focus_set->focus_stack_normal, - tag->focus_set->focus_stack_normal); - wlr_list_cat(new_tag->focus_set->focus_stack_not_focusable, - tag->focus_set->focus_stack_not_focusable); - - wlr_list_cat(new_tag->visible_con_set->tiled_containers, - tag->visible_con_set->tiled_containers); - - wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_background, - tag->visible_focus_set->focus_stack_layer_background); - wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_bottom, - tag->visible_focus_set->focus_stack_layer_bottom); - wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_top, - tag->visible_focus_set->focus_stack_layer_top); - wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_overlay, - tag->visible_focus_set->focus_stack_layer_overlay); - wlr_list_cat(new_tag->visible_focus_set->focus_stack_on_top, - tag->visible_focus_set->focus_stack_on_top); - wlr_list_cat(new_tag->visible_focus_set->focus_stack_normal, - tag->visible_focus_set->focus_stack_normal); - wlr_list_cat(new_tag->visible_focus_set->focus_stack_not_focusable, - tag->visible_focus_set->focus_stack_not_focusable); - - return new_tag; + // no number has more than 11 digits when int is 32 bit long + char name[12]; + // TODO explain why +1 + snprintf(name, 12, "%d:%d", tag_id, c_idx_to_lua_idx(tag_id)); + + struct tag *new_tag = create_tag(name, tag_id, server.default_layout); + int *tag_id_ptr = malloc(sizeof(*tag_id_ptr)); + *tag_id_ptr = tag_id; + g_hash_table_insert(server.tags, tag_id_ptr, new_tag); + struct tag *tag = get_tag(0); + wlr_list_cat(new_tag->con_set->tiled_containers, + tag->con_set->tiled_containers); + + wlr_list_cat(new_tag->focus_set->focus_stack_layer_background, + tag->focus_set->focus_stack_layer_background); + wlr_list_cat(new_tag->focus_set->focus_stack_layer_bottom, + tag->focus_set->focus_stack_layer_bottom); + wlr_list_cat(new_tag->focus_set->focus_stack_layer_top, + tag->focus_set->focus_stack_layer_top); + wlr_list_cat(new_tag->focus_set->focus_stack_layer_overlay, + tag->focus_set->focus_stack_layer_overlay); + wlr_list_cat(new_tag->focus_set->focus_stack_on_top, + tag->focus_set->focus_stack_on_top); + wlr_list_cat(new_tag->focus_set->focus_stack_normal, + tag->focus_set->focus_stack_normal); + wlr_list_cat(new_tag->focus_set->focus_stack_not_focusable, + tag->focus_set->focus_stack_not_focusable); + + wlr_list_cat(new_tag->visible_con_set->tiled_containers, + tag->visible_con_set->tiled_containers); + + wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_background, + tag->visible_focus_set->focus_stack_layer_background); + wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_bottom, + tag->visible_focus_set->focus_stack_layer_bottom); + wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_top, + tag->visible_focus_set->focus_stack_layer_top); + wlr_list_cat(new_tag->visible_focus_set->focus_stack_layer_overlay, + tag->visible_focus_set->focus_stack_layer_overlay); + wlr_list_cat(new_tag->visible_focus_set->focus_stack_on_top, + tag->visible_focus_set->focus_stack_on_top); + wlr_list_cat(new_tag->visible_focus_set->focus_stack_normal, + tag->visible_focus_set->focus_stack_normal); + wlr_list_cat(new_tag->visible_focus_set->focus_stack_not_focusable, + tag->visible_focus_set->focus_stack_not_focusable); + + return new_tag; } static void init_lists(struct server *server) { - server->layer_visual_stack_lists = g_ptr_array_new(); + server->layer_visual_stack_lists = g_ptr_array_new(); - server->layer_visual_stack_background = g_ptr_array_new(); - server->layer_visual_stack_bottom = g_ptr_array_new(); - server->layer_visual_stack_top = g_ptr_array_new(); - server->layer_visual_stack_overlay = g_ptr_array_new(); + server->layer_visual_stack_background = g_ptr_array_new(); + server->layer_visual_stack_bottom = g_ptr_array_new(); + server->layer_visual_stack_top = g_ptr_array_new(); + server->layer_visual_stack_overlay = g_ptr_array_new(); - g_ptr_array_add(server->layer_visual_stack_lists, - server->layer_visual_stack_overlay); - g_ptr_array_add(server->layer_visual_stack_lists, - server->layer_visual_stack_top); - g_ptr_array_add(server->layer_visual_stack_lists, - server->layer_visual_stack_bottom); - g_ptr_array_add(server->layer_visual_stack_lists, - server->layer_visual_stack_background); + g_ptr_array_add(server->layer_visual_stack_lists, + server->layer_visual_stack_overlay); + g_ptr_array_add(server->layer_visual_stack_lists, + server->layer_visual_stack_top); + g_ptr_array_add(server->layer_visual_stack_lists, + server->layer_visual_stack_bottom); + g_ptr_array_add(server->layer_visual_stack_lists, + server->layer_visual_stack_background); } static void finalize_lists(struct server *server) { - g_ptr_array_unref(server->layer_visual_stack_background); - g_ptr_array_unref(server->layer_visual_stack_bottom); - g_ptr_array_unref(server->layer_visual_stack_top); - g_ptr_array_unref(server->layer_visual_stack_overlay); + g_ptr_array_unref(server->layer_visual_stack_background); + g_ptr_array_unref(server->layer_visual_stack_bottom); + g_ptr_array_unref(server->layer_visual_stack_top); + g_ptr_array_unref(server->layer_visual_stack_overlay); - g_ptr_array_unref(server->layer_visual_stack_lists); + g_ptr_array_unref(server->layer_visual_stack_lists); } static int clear_key_combo_timer_callback(void *data) { - GPtrArray *registered_key_combos = server.registered_key_combos; - char *bind = join_string((const char **)registered_key_combos->pdata, - registered_key_combos->len, " "); + GPtrArray *registered_key_combos = server.registered_key_combos; + char *bind = join_string((const char **)registered_key_combos->pdata, + registered_key_combos->len, " "); - struct tag *tag = server_get_selected_tag(); - struct layout *lt = tag_get_layout(tag); + struct tag *tag = server_get_selected_tag(); + struct layout *lt = tag_get_layout(tag); - process_binding(lt, bind); - free(bind); + process_binding(lt, bind); + free(bind); - list_clear(server.registered_key_combos, free); - return 0; + list_clear(server.registered_key_combos, free); + return 0; } static void init_timers(struct server *server) { - server->combo_timer_source = wl_event_loop_add_timer( - server->wl_event_loop, clear_key_combo_timer_callback, - server->registered_key_combos); + server->combo_timer_source = wl_event_loop_add_timer( + server->wl_event_loop, clear_key_combo_timer_callback, + server->registered_key_combos); } static void finalize_timers(struct server *server) { - wl_event_source_remove(server->combo_timer_source); + wl_event_source_remove(server->combo_timer_source); } static int init_backend(struct server *server) { - /* The Wayland display is managed by libwayland. It handles accepting - * clients from the Unix socket, manging Wayland globals, and so on. */ - server->wl_display = wl_display_create(); - server->wl_event_loop = wl_display_get_event_loop(server->wl_display); + /* The Wayland display is managed by libwayland. It handles accepting + * clients from the Unix socket, manging Wayland globals, and so on. */ + server->wl_display = wl_display_create(); + server->wl_event_loop = wl_display_get_event_loop(server->wl_display); + + init_timers(server); + + /* The backend is a wlroots feature which abstracts the underlying input and + * output hardware. The autocreate option will choose the most suitable + * backend based on the current environment, such as opening an X11 window + * if an X11 server is running. The NULL argument here optionally allows you + * to pass in a custom renderer if wlr_renderer doesnt). */ + if (!(server->backend = wlr_backend_autocreate(server->wl_display, &server->wlr_session))) { + printf("couldn't create backend\n"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +static void init_xdg_shell(struct server *server) { + server->xdg_shell = wlr_xdg_shell_create(server->wl_display, XDG_SHELL_VERSION); + wlr_server_decoration_manager_set_default_mode( + wlr_server_decoration_manager_create(server->wl_display), + WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); + LISTEN(&server->xdg_shell->events.new_surface, &server->new_xdg_surface, + create_notify_xdg); +} + +static void init_layer_shell(struct server *server) { + server->layer_shell = wlr_layer_shell_v1_create(server->wl_display, LAYER_SHELL_VERSION); + LISTEN(&server->layer_shell->events.new_surface, + &server->new_layer_shell_surface, create_notify_layer_shell); +} - init_timers(server); +static void init_output_management(struct server *server) { + LISTEN(&server->backend->events.new_output, &server->new_output, + create_monitor); + server->output_mgr = wlr_output_manager_v1_create(server->wl_display); + LISTEN(&server->output_mgr->events.apply, &server->output_mgr_apply, + handle_output_mgr_apply); + LISTEN(&server->output_mgr->events.test, &server->output_mgr_test, + handle_output_mgr_test); +} - /* The backend is a wlroots feature which abstracts the underlying input and - * output hardware. The autocreate option will choose the most suitable - * backend based on the current environment, such as opening an X11 window - * if an X11 server is running. The NULL argument here optionally allows you - * to pass in a custom renderer if wlr_renderer doesnt). */ - if (!(server->backend = wlr_backend_autocreate(server->wl_display, &server->wlr_session))) { - printf("couldn't create backend\n"); - return EXIT_FAILURE; - } - return EXIT_SUCCESS; +static void init_pointer_constraints(struct server *server) { + server->pointer_constraints = wlr_pointer_constraints_v1_create(server->wl_display); + LISTEN(&server->pointer_constraints->events.new_constraint, + &server->new_pointer_constraint, handle_new_pointer_constraint); } static void init_event_handlers(struct server *server) { - LISTEN(&server->backend->events.new_output, &server->new_output, - create_monitor); - /* Use xdg_decoration protocol to negotiate server-side decorations */ - server->xdeco_mgr = wlr_xdg_decoration_manager_v1_create(server->wl_display); - LISTEN(&server->xdeco_mgr->events.new_toplevel_decoration, &server->new_xdeco, - createxdeco); - - server->xdg_shell = - wlr_xdg_shell_create(server->wl_display, XDG_SHELL_VERSION); - // remove csd(client side decorations) completely from xdg based windows - wlr_server_decoration_manager_set_default_mode( - wlr_server_decoration_manager_create(server->wl_display), - WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); - LISTEN(&server->xdg_shell->events.new_surface, &server->new_xdg_surface, - create_notify_xdg); - - server->layer_shell = wlr_layer_shell_v1_create(server->wl_display, LAYER_SHELL_VERSION); - LISTEN(&server->layer_shell->events.new_surface, - &server->new_layer_shell_surface, create_notify_layer_shell); - - server->pointer_constraints = - wlr_pointer_constraints_v1_create(server->wl_display); - LISTEN(&server->pointer_constraints->events.new_constraint, - &server->new_pointer_constraint, handle_new_pointer_constraint); - - server->output_mgr = wlr_output_manager_v1_create(server->wl_display); - LISTEN(&server->output_mgr->events.apply, &server->output_mgr_apply, - handle_output_mgr_apply); - LISTEN(&server->output_mgr->events.test, &server->output_mgr_test, - handle_output_mgr_test); - - server->tablet_mgr = wlr_tablet_v2_create(server->wl_display); + // Initialize XDG Shell and related decorations + init_xdg_shell(server); + + // Initialize Layer Shell for creating layers + init_layer_shell(server); + + // Setup output management + init_output_management(server); + + // Setup pointer constraints + init_pointer_constraints(server); + + // Initialize other protocols as needed... } static void finalize_event_handlers(struct server *server) { - destroy_event_handler(server->event_handler); + destroy_event_handler(server->event_handler); } void init_server() { - server = (struct server){}; + server = (struct server){}; - server.registered_key_combos = g_ptr_array_new(); - server.named_key_combos = g_ptr_array_new(); - server.error_path = strdup("$HOME/.config/japokwm"); - expand_path(&server.error_path); + server.registered_key_combos = g_ptr_array_new(); + server.named_key_combos = g_ptr_array_new(); + server.error_path = strdup("$HOME/.config/japokwm"); + expand_path(&server.error_path); - init_lists(&server); + init_lists(&server); - server.mons = g_ptr_array_new(); - server.popups = g_ptr_array_new(); - server.xwayland_popups = g_ptr_array_new(); + server.mons = g_ptr_array_new(); + server.popups = g_ptr_array_new(); + server.xwayland_popups = g_ptr_array_new(); - server.scratchpad = g_ptr_array_new(); - server.keyboards = g_ptr_array_new(); - server.config_paths = create_default_config_paths(); - server.user_data_paths = create_default_user_data_paths(); - server.layout_paths = create_default_layout_paths(); - server.tags = create_tags(); + server.scratchpad = g_ptr_array_new(); + server.keyboards = g_ptr_array_new(); + server.config_paths = create_default_config_paths(); + server.user_data_paths = create_default_user_data_paths(); + server.layout_paths = create_default_layout_paths(); + server.tags = create_tags(); - server.container_stack = g_ptr_array_new(); + server.container_stack = g_ptr_array_new(); - server.event_handler = create_event_handler(); + server.event_handler = create_event_handler(); - server.previous_tag = 0; - server.previous_bitset = bitset_create(); + server.previous_tag = 0; + server.previous_bitset = bitset_create(); - server_prohibit_reloading_config(); + server_prohibit_reloading_config(); - init_lua_api(&server); - init_error_file(); + init_lua_api(&server); + init_error_file(); - server.default_layout_ring = create_ring_buffer(); - server_reset_layout_ring(server.default_layout_ring); + server.default_layout_ring = create_ring_buffer(); + server_reset_layout_ring(server.default_layout_ring); - server.default_layout = create_layout(L); + server.default_layout = create_layout(L); - load_lua_api(L); - if (init_backend(&server) != EXIT_SUCCESS) { - return; - } + load_lua_api(L); + if (init_backend(&server) != EXIT_SUCCESS) { + return; + } - ipc_init(server.wl_event_loop); + ipc_init(server.wl_event_loop); - /* Creates an output layout, which a wlroots utility for working with an - * arrangement of screens in a physical layout. */ - server.output_layout = wlr_output_layout_create(); + /* Creates an output layout, which a wlroots utility for working with an + * arrangement of screens in a physical layout. */ + server.output_layout = wlr_output_layout_create(); } void finalize_server() { - g_ptr_array_unref(server.registered_key_combos); - g_ptr_array_unref(server.named_key_combos); + g_ptr_array_unref(server.registered_key_combos); + g_ptr_array_unref(server.named_key_combos); - finalize_lists(&server); - finalize_event_handlers(&server); + finalize_lists(&server); + finalize_event_handlers(&server); - bitset_destroy(server.previous_bitset); + bitset_destroy(server.previous_bitset); - // NOTE: these bitsets are created lazily, so they may be NULL but that is - // ok since bitset_destroy handles this case. - bitset_destroy(server.tmp_bitset); - bitset_destroy(server.local_tmp_bitset); + // NOTE: these bitsets are created lazily, so they may be NULL but that is + // ok since bitset_destroy handles this case. + bitset_destroy(server.tmp_bitset); + bitset_destroy(server.local_tmp_bitset); - g_ptr_array_unref(server.mons); - g_ptr_array_unref(server.popups); - g_ptr_array_unref(server.xwayland_popups); + g_ptr_array_unref(server.mons); + g_ptr_array_unref(server.popups); + g_ptr_array_unref(server.xwayland_popups); - g_ptr_array_unref(server.scratchpad); - g_ptr_array_unref(server.keyboards); - g_ptr_array_unref(server.config_paths); - g_ptr_array_unref(server.user_data_paths); - g_ptr_array_unref(server.layout_paths); + g_ptr_array_unref(server.scratchpad); + g_ptr_array_unref(server.keyboards); + g_ptr_array_unref(server.config_paths); + g_ptr_array_unref(server.user_data_paths); + g_ptr_array_unref(server.layout_paths); - g_ptr_array_unref(server.container_stack); + g_ptr_array_unref(server.container_stack); } void server_terminate(struct server *server) { - server->is_running = false; - wl_display_terminate(server->wl_display); - uv_loop_close(server->uv_loop); + server->is_running = false; + wl_display_terminate(server->wl_display); + uv_loop_close(server->uv_loop); } static void run_event_loop() { - int pfd_size = 2; - struct pollfd pfds[pfd_size]; + int pfd_size = 2; + struct pollfd pfds[pfd_size]; - pfds[0].fd = wl_event_loop_get_fd(server.wl_event_loop); - pfds[0].events = POLLIN; + pfds[0].fd = wl_event_loop_get_fd(server.wl_event_loop); + pfds[0].events = POLLIN; - pfds[1].fd = uv_backend_fd(server.uv_loop); - pfds[1].events = POLLIN; + pfds[1].fd = uv_backend_fd(server.uv_loop); + pfds[1].events = POLLIN; - server.is_running = 1; - while (server.is_running) { - wl_display_flush_clients(server.wl_display); + server.is_running = 1; + while (server.is_running) { + wl_display_flush_clients(server.wl_display); - /* poll waits for any event of either the wayland event loop or the - * libuv event loop and only if one emits an event we continue */ - poll(pfds, pfd_size, -1); + /* poll waits for any event of either the wayland event loop or the + * libuv event loop and only if one emits an event we continue */ + poll(pfds, pfd_size, -1); - // TODO: we can probably run this more efficiently - uv_run(server.uv_loop, UV_RUN_NOWAIT); - wl_event_loop_dispatch(server.wl_event_loop, 0); - } + // TODO: we can probably run this more efficiently + uv_run(server.uv_loop, UV_RUN_NOWAIT); + wl_event_loop_dispatch(server.wl_event_loop, 0); + } } static void run(char *startup_cmd) { - pid_t startup_pid = -1; - - /* Add a Unix socket to the Wayland display. */ - const char *socket = wl_display_add_socket_auto(server.wl_display); - - if (!socket) - printf("startup: display_add_socket_auto\n"); - - /* Set the WAYLAND_DISPLAY environment variable to our socket and run the - * startup command if requested. */ - setenv("WAYLAND_DISPLAY", socket, 1); - - /* Start the backend. This will enumerate outputs and inputs, become the DRM - * master, etc */ - if (!wlr_backend_start(server.backend)) { - printf("Failed to start backend"); - wlr_backend_destroy(server.backend); - return; - } - - /* Now that outputs are initialized, choose initial selMon based on - * cursor position, and set default cursor image */ - update_monitor_geometries(); - struct seat *seat = input_manager_get_default_seat(); - struct cursor *cursor = seat->cursor; - struct monitor *m = - xy_to_monitor(cursor->wlr_cursor->x, cursor->wlr_cursor->y); - focus_monitor(m); - - /* XXX hack to get cursor to display in its initial location (100, 100) - * instead of (0, 0) and then jumping. still may not be fully - * initialized, as the image/coordinates are not transformed for the - * monitor when displayed here */ - wlr_cursor_warp_closest(seat->cursor->wlr_cursor, NULL, cursor->wlr_cursor->x, - cursor->wlr_cursor->y); - wlr_cursor_set_xcursor(cursor->wlr_cursor, seat->cursor->xcursor_mgr, - "left_ptr"); - - if (startup_cmd) { - startup_pid = fork(); - if (startup_pid == 0) { - execl("/bin/sh", "/bin/sh", "-c", startup_cmd, (void *)NULL); + pid_t startup_pid = -1; + + /* Add a Unix socket to the Wayland display. */ + const char *socket = wl_display_add_socket_auto(server.wl_display); + + if (!socket) + printf("startup: display_add_socket_auto\n"); + + /* Set the WAYLAND_DISPLAY environment variable to our socket and run the + * startup command if requested. */ + setenv("WAYLAND_DISPLAY", socket, 1); + + /* Start the backend. This will enumerate outputs and inputs, become the DRM + * master, etc */ + if (!wlr_backend_start(server.backend)) { + printf("Failed to start backend"); + wlr_backend_destroy(server.backend); + return; + } + + /* Now that outputs are initialized, choose initial selMon based on + * cursor position, and set default cursor image */ + update_monitor_geometries(); + struct seat *seat = input_manager_get_default_seat(); + struct cursor *cursor = seat->cursor; + struct monitor *m = + xy_to_monitor(cursor->wlr_cursor->x, cursor->wlr_cursor->y); + focus_monitor(m); + + /* XXX hack to get cursor to display in its initial location (100, 100) + * instead of (0, 0) and then jumping. still may not be fully + * initialized, as the image/coordinates are not transformed for the + * monitor when displayed here */ + wlr_cursor_warp_closest(seat->cursor->wlr_cursor, NULL, cursor->wlr_cursor->x, + cursor->wlr_cursor->y); + wlr_cursor_set_xcursor(cursor->wlr_cursor, seat->cursor->xcursor_mgr, + "left_ptr"); + + if (startup_cmd) { + startup_pid = fork(); + if (startup_pid == 0) { + execl("/bin/sh", "/bin/sh", "-c", startup_cmd, (void *)NULL); + } } - } - run_event_loop(); + run_event_loop(); - if (startup_cmd) { - kill(startup_pid, SIGTERM); - waitpid(startup_pid, NULL, 0); - } + if (startup_cmd) { + kill(startup_pid, SIGTERM); + waitpid(startup_pid, NULL, 0); + } } static void init_lua_api(struct server *server) { - L = luaL_newstate(); - luaL_openlibs(L); - lua_setwarnf(L, handle_warning, NULL); + L = luaL_newstate(); + luaL_openlibs(L); + lua_setwarnf(L, handle_warning, NULL); } static void finalize_lua_api(struct server *server) { lua_close(L); } void server_reset_layout_ring(struct ring_buffer *layout_ring) { - list_clear(layout_ring->names, NULL); - g_ptr_array_add(layout_ring->names, strdup("tile")); - g_ptr_array_add(layout_ring->names, strdup("monocle")); + list_clear(layout_ring->names, NULL); + g_ptr_array_add(layout_ring->names, strdup("tile")); + g_ptr_array_add(layout_ring->names, strdup("monocle")); } static void _async_handler_function(struct uv_async_s *arg) { - // struct function_data *func_data = data->data; - // printf("the end\n"); - // free(func_data->output); + // struct function_data *func_data = data->data; + // printf("the end\n"); + // free(func_data->output); - struct function_data *data = arg->data; + struct function_data *data = arg->data; - lua_State *L = data->L; - int func_ref = data->lua_func_ref; - printf("the end %d\n", func_ref); + lua_State *L = data->L; + int func_ref = data->lua_func_ref; + printf("the end %d\n", func_ref); - lua_rawgeti(L, LUA_REGISTRYINDEX, func_ref); - lua_pushstring(L, data->output); - lua_call_safe(L, 1, 0, 0); - luaL_unref(L, LUA_REGISTRYINDEX, func_ref); + lua_rawgeti(L, LUA_REGISTRYINDEX, func_ref); + lua_pushstring(L, data->output); + lua_call_safe(L, 1, 0, 0); + luaL_unref(L, LUA_REGISTRYINDEX, func_ref); - free(data); + free(data); } int setup_server(struct server *server) { - server->uv_loop = uv_default_loop(); - - uv_async_init(uv_default_loop(), &server->async_handler, - _async_handler_function); - - /* If we don't provide a renderer, autocreate makes a GLES2 renderer for us. - * The renderer is responsible for defining the various pixel formats it - * supports for shared memory, this configures that for clients. */ - server->renderer = wlr_renderer_autocreate(server->backend); - - wlr_renderer_init_wl_display(server->renderer, server->wl_display); - - server->allocator = - wlr_allocator_autocreate(server->backend, server->renderer); - - /* This creates some hands-off wlroots interfaces. The compositor is - * necessary for clients to allocate surfaces and the data device manager - * handles the clipboard. Each of these wlroots interfaces has room for you - * to dig your fingers in and play with their behavior if you want. Note that - * the clients cannot set the selection directly without compositor approval, - * see the setsel() function. */ - - server->compositor = - wlr_compositor_create(server->wl_display, WL_COMPOSITOR_VERSION, server->renderer); - - wlr_subcompositor_create(server->wl_display); - - wlr_export_dmabuf_manager_v1_create(server->wl_display); - wlr_screencopy_manager_v1_create(server->wl_display); - wlr_data_control_manager_v1_create(server->wl_display); - wlr_data_device_manager_create(server->wl_display); - wlr_gamma_control_manager_v1_create(server->wl_display); - wlr_primary_selection_v1_device_manager_create(server->wl_display); - wlr_viewporter_create(server->wl_display); - // TODO: do we still need that? - // wlr_idle_create(server->wl_display); - wlr_idle_inhibit_v1_create(server->wl_display); - - wlr_xdg_output_manager_v1_create(server->wl_display, server->output_layout); - - /* Set up the xdg-shell. The xdg-shell is a - * Wayland protocol which is used for application windows. For more - * detail on shells, refer to the article: - * - * https://drewdevault.com/2018/07/29/Wayland-shells.html - */ - - server->input_inhibitor_mgr = - wlr_input_inhibit_manager_create(server->wl_display); - - /* setup virtual pointer manager*/ - server->virtual_pointer_mgr = - wlr_virtual_pointer_manager_v1_create(server->wl_display); - - /* setup virtual keyboard manager */ - server->virtual_keyboard_mgr = - wlr_virtual_keyboard_manager_v1_create(server->wl_display); - - /* setup relative pointer manager */ - server->relative_pointer_mgr = - wlr_relative_pointer_manager_v1_create(server->wl_display); - /* wl_signal_add(&server.virtual_keyboard_mgr->events.new_virtual_keyboard, - * &new_virtual_keyboard); */ - init_event_handlers(server); - - /* - * Configures a seat, which is a single "seat" at which a user sits and - * operates the computer. This conceptually includes up to one keyboard, - * pointer, touch, and drawing tablet device. We also rig up a listener to - * let us know when new input devices are available on the backend. - */ - server->input_manager = create_input_manager(); - struct seat *seat = create_seat("seat0"); - g_ptr_array_add(server->input_manager->seats, seat); - - server->output_mgr = wlr_output_manager_v1_create(server->wl_display); - wl_signal_add(&server->output_mgr->events.apply, &server->output_mgr_apply); - wl_signal_add(&server->output_mgr->events.test, &server->output_mgr_test); - - server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); - - server->scene = wlr_scene_create(); - struct wlr_scene *server_scene = server->scene; - server->scene_background = wlr_scene_tree_create(&server_scene->tree); - server->scene_tiled = wlr_scene_tree_create(&server_scene->tree); - server->scene_floating = wlr_scene_tree_create(&server_scene->tree); - server->scene_popups = wlr_scene_tree_create(&server_scene->tree); - server->scene_overlay = wlr_scene_tree_create(&server_scene->tree); - - server->new_surface.notify = server_handle_new_surface; - wl_signal_add(&server->compositor->events.new_surface, &server->new_surface); + server->uv_loop = uv_default_loop(); + + uv_async_init(uv_default_loop(), &server->async_handler, + _async_handler_function); + + /* If we don't provide a renderer, autocreate makes a GLES2 renderer for us. + * The renderer is responsible for defining the various pixel formats it + * supports for shared memory, this configures that for clients. */ + server->renderer = wlr_renderer_autocreate(server->backend); + + wlr_renderer_init_wl_display(server->renderer, server->wl_display); + + server->allocator = + wlr_allocator_autocreate(server->backend, server->renderer); + + /* This creates some hands-off wlroots interfaces. The compositor is + * necessary for clients to allocate surfaces and the data device manager + * handles the clipboard. Each of these wlroots interfaces has room for you + * to dig your fingers in and play with their behavior if you want. Note that + * the clients cannot set the selection directly without compositor approval, + * see the setsel() function. */ + + server->compositor = + wlr_compositor_create(server->wl_display, WL_COMPOSITOR_VERSION, server->renderer); + + wlr_subcompositor_create(server->wl_display); + + wlr_export_dmabuf_manager_v1_create(server->wl_display); + wlr_screencopy_manager_v1_create(server->wl_display); + wlr_data_control_manager_v1_create(server->wl_display); + wlr_data_device_manager_create(server->wl_display); + wlr_gamma_control_manager_v1_create(server->wl_display); + wlr_primary_selection_v1_device_manager_create(server->wl_display); + wlr_viewporter_create(server->wl_display); + // TODO: do we still need that? + // wlr_idle_create(server->wl_display); + wlr_idle_inhibit_v1_create(server->wl_display); + + wlr_xdg_output_manager_v1_create(server->wl_display, server->output_layout); + + /* Set up the xdg-shell. The xdg-shell is a + * Wayland protocol which is used for application windows. For more + * detail on shells, refer to the article: + * + * https://drewdevault.com/2018/07/29/Wayland-shells.html + */ + + server->input_inhibitor_mgr = + wlr_input_inhibit_manager_create(server->wl_display); + + /* setup virtual pointer manager*/ + server->virtual_pointer_mgr = + wlr_virtual_pointer_manager_v1_create(server->wl_display); + + /* setup virtual keyboard manager */ + server->virtual_keyboard_mgr = + wlr_virtual_keyboard_manager_v1_create(server->wl_display); + + /* setup relative pointer manager */ + server->relative_pointer_mgr = + wlr_relative_pointer_manager_v1_create(server->wl_display); + /* wl_signal_add(&server.virtual_keyboard_mgr->events.new_virtual_keyboard, + * &new_virtual_keyboard); */ + init_event_handlers(server); + + /* + * Configures a seat, which is a single "seat" at which a user sits and + * operates the computer. This conceptually includes up to one keyboard, + * pointer, touch, and drawing tablet device. We also rig up a listener to + * let us know when new input devices are available on the backend. + */ + server->input_manager = create_input_manager(); + struct seat *seat = create_seat("seat0"); + g_ptr_array_add(server->input_manager->seats, seat); + + server->output_mgr = wlr_output_manager_v1_create(server->wl_display); + wl_signal_add(&server->output_mgr->events.apply, &server->output_mgr_apply); + wl_signal_add(&server->output_mgr->events.test, &server->output_mgr_test); + + server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); + + server->scene = wlr_scene_create(); + struct wlr_scene *server_scene = server->scene; + server->scene_background = wlr_scene_tree_create(&server_scene->tree); + server->scene_tiled = wlr_scene_tree_create(&server_scene->tree); + server->scene_floating = wlr_scene_tree_create(&server_scene->tree); + server->scene_popups = wlr_scene_tree_create(&server_scene->tree); + server->scene_overlay = wlr_scene_tree_create(&server_scene->tree); + + server->new_surface.notify = server_handle_new_surface; + wl_signal_add(&server->compositor->events.new_surface, &server->new_surface); #ifdef JAPOKWM_HAS_XWAYLAND - init_xwayland(server->wl_display, seat); + init_xwayland(server->wl_display, seat); #endif - return 0; + return 0; } int start_server(char *startup_cmd) { - if (setup_server(&server)) { - printf("failed to setup japokwm\n"); - return EXIT_FAILURE; - } + if (setup_server(&server)) { + printf("failed to setup japokwm\n"); + return EXIT_FAILURE; + } - run(startup_cmd); - return EXIT_SUCCESS; + run(startup_cmd); + return EXIT_SUCCESS; } int finalize(struct server *server) { - finalize_timers(server); - destroy_layout(server->default_layout); - destroy_ring_buffer(server->default_layout_ring); - return 0; + finalize_timers(server); + destroy_layout(server->default_layout); + destroy_ring_buffer(server->default_layout_ring); + return 0; } int stop_server() { #if JAPOKWM_HAS_XWAYLAND - wlr_xwayland_destroy(server.xwayland.wlr_xwayland); + wlr_xwayland_destroy(server.xwayland.wlr_xwayland); #endif - wl_display_destroy_clients(server.wl_display); + wl_display_destroy_clients(server.wl_display); - finalize(&server); + finalize(&server); - close_error_file(); - wlr_output_layout_destroy(server.output_layout); - wl_display_destroy(server.wl_display); - destroy_input_manager(server.input_manager); - destroy_tags(server.tags); + close_error_file(); + wlr_output_layout_destroy(server.output_layout); + wl_display_destroy(server.wl_display); + destroy_input_manager(server.input_manager); + destroy_tags(server.tags); - finalize_lua_api(&server); - return EXIT_SUCCESS; + finalize_lua_api(&server); + return EXIT_SUCCESS; } int server_get_tag_count() { - size_t len = server.default_layout->options->tag_names->len; - return len; + size_t len = server.default_layout->options->tag_names->len; + return len; } int server_get_tag_key_count() { - size_t count = g_hash_table_size(server.tags); - return count; + size_t count = g_hash_table_size(server.tags); + return count; } GList *server_get_tags() { - GList *values = g_hash_table_get_values(server.tags); - return values; + GList *values = g_hash_table_get_values(server.tags); + return values; } struct tag *get_tag(int id) { - if (id < 0) - return NULL; - struct tag *tag = g_hash_table_lookup(server.tags, &id); - if (!tag) { - tag = handle_too_few_tags(id); - assert(tag != NULL); - } + if (id < 0) + return NULL; + struct tag *tag = g_hash_table_lookup(server.tags, &id); + if (!tag) { + tag = handle_too_few_tags(id); + assert(tag != NULL); + } - return tag; + return tag; } struct monitor *server_get_selected_monitor() { - return server.selected_monitor; + return server.selected_monitor; } void server_set_selected_monitor(struct monitor *m) { - server.selected_monitor = m; + server.selected_monitor = m; } void server_center_default_cursor_in_monitor(struct monitor *m) { - struct seat *seat = input_manager_get_default_seat(); - struct cursor *cursor = seat->cursor; - center_cursor_in_monitor(cursor, m); + struct seat *seat = input_manager_get_default_seat(); + struct cursor *cursor = seat->cursor; + center_cursor_in_monitor(cursor, m); } BitSet *server_bitset_get_tmp() { - if (!server.tmp_bitset) { - server.tmp_bitset = bitset_create(); - } - return server.tmp_bitset; + if (!server.tmp_bitset) { + server.tmp_bitset = bitset_create(); + } + return server.tmp_bitset; } BitSet *server_bitset_get_tmp_copy(BitSet *bitset) { - BitSet *tmp = server_bitset_get_tmp(); - bitset_assign_bitset(&tmp, bitset); - return tmp; + BitSet *tmp = server_bitset_get_tmp(); + bitset_assign_bitset(&tmp, bitset); + return tmp; } BitSet *server_bitset_get_local_tmp() { - if (!server.local_tmp_bitset) { - server.local_tmp_bitset = bitset_create(); - } + if (!server.local_tmp_bitset) { + server.local_tmp_bitset = bitset_create(); + } - return server.local_tmp_bitset; + return server.local_tmp_bitset; } BitSet *server_bitset_get_local_tmp_copy(BitSet *bitset) { - BitSet *tmp = server_bitset_get_local_tmp(); - bitset_assign_bitset(&tmp, bitset); - return tmp; + BitSet *tmp = server_bitset_get_local_tmp(); + bitset_assign_bitset(&tmp, bitset); + return tmp; } struct tag *server_get_selected_tag() { From 00670df928be77cfeb57da80a6a3fdd10768822f Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Sun, 31 Dec 2023 14:58:16 +0100 Subject: [PATCH 29/37] refactor: refactor server.c --- src/server.c | 65 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/src/server.c b/src/server.c index e9b892dc..09c1d96e 100644 --- a/src/server.c +++ b/src/server.c @@ -177,50 +177,75 @@ static int init_backend(struct server *server) { } static void init_xdg_shell(struct server *server) { - server->xdg_shell = wlr_xdg_shell_create(server->wl_display, XDG_SHELL_VERSION); + /* Use xdg_decoration protocol to negotiate server-side decorations */ + server->xdeco_mgr = wlr_xdg_decoration_manager_v1_create(server->wl_display); + LISTEN(&server->xdeco_mgr->events.new_toplevel_decoration, &server->new_xdeco, + createxdeco); + + server->xdg_shell = + wlr_xdg_shell_create(server->wl_display, XDG_SHELL_VERSION); + // remove csd(client side decorations) completely from xdg based windows wlr_server_decoration_manager_set_default_mode( - wlr_server_decoration_manager_create(server->wl_display), - WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); + wlr_server_decoration_manager_create(server->wl_display), + WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); LISTEN(&server->xdg_shell->events.new_surface, &server->new_xdg_surface, - create_notify_xdg); + create_notify_xdg); } static void init_layer_shell(struct server *server) { server->layer_shell = wlr_layer_shell_v1_create(server->wl_display, LAYER_SHELL_VERSION); LISTEN(&server->layer_shell->events.new_surface, - &server->new_layer_shell_surface, create_notify_layer_shell); + &server->new_layer_shell_surface, create_notify_layer_shell); } static void init_output_management(struct server *server) { LISTEN(&server->backend->events.new_output, &server->new_output, - create_monitor); + create_monitor); server->output_mgr = wlr_output_manager_v1_create(server->wl_display); LISTEN(&server->output_mgr->events.apply, &server->output_mgr_apply, - handle_output_mgr_apply); + handle_output_mgr_apply); LISTEN(&server->output_mgr->events.test, &server->output_mgr_test, - handle_output_mgr_test); + handle_output_mgr_test); } static void init_pointer_constraints(struct server *server) { - server->pointer_constraints = wlr_pointer_constraints_v1_create(server->wl_display); + server->pointer_constraints = + wlr_pointer_constraints_v1_create(server->wl_display); LISTEN(&server->pointer_constraints->events.new_constraint, - &server->new_pointer_constraint, handle_new_pointer_constraint); + &server->new_pointer_constraint, handle_new_pointer_constraint); +} + +// static void init_event_handlers(struct server *server) { +// // Initialize XDG Shell and related decorations +// init_xdg_shell(server); +// +// // Initialize Layer Shell for creating layers +// init_layer_shell(server); +// +// // Setup output management +// init_output_management(server); +// +// // Setup pointer constraints +// init_pointer_constraints(server); +// +// // Initialize other protocols as needed... +// } +// + +static void init_tablet_v2(struct server *server) { + server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); } -static void init_event_handlers(struct server *server) { - // Initialize XDG Shell and related decorations - init_xdg_shell(server); +static void init_event_handlers(struct server *server) +{ + init_output_management(server); - // Initialize Layer Shell for creating layers + init_xdg_shell(server); init_layer_shell(server); - // Setup output management - init_output_management(server); - - // Setup pointer constraints + // input methods init_pointer_constraints(server); - - // Initialize other protocols as needed... + init_tablet_v2(server); } static void finalize_event_handlers(struct server *server) { From b9f810d9a368d3b6582c4694bafb276543208493 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Sun, 31 Dec 2023 14:58:27 +0100 Subject: [PATCH 30/37] refactor: refactor stuff --- src/server.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/server.c b/src/server.c index 09c1d96e..eab9db13 100644 --- a/src/server.c +++ b/src/server.c @@ -215,23 +215,6 @@ static void init_pointer_constraints(struct server *server) { &server->new_pointer_constraint, handle_new_pointer_constraint); } -// static void init_event_handlers(struct server *server) { -// // Initialize XDG Shell and related decorations -// init_xdg_shell(server); -// -// // Initialize Layer Shell for creating layers -// init_layer_shell(server); -// -// // Setup output management -// init_output_management(server); -// -// // Setup pointer constraints -// init_pointer_constraints(server); -// -// // Initialize other protocols as needed... -// } -// - static void init_tablet_v2(struct server *server) { server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); } From 101f4958d5db119f1b16a471f8bf1064c0ec7d7d Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Sun, 31 Dec 2023 15:03:44 +0100 Subject: [PATCH 31/37] refactor: refactor run function --- src/server.c | 67 +++++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/src/server.c b/src/server.c index eab9db13..b387a57d 100644 --- a/src/server.c +++ b/src/server.c @@ -342,50 +342,57 @@ static void run_event_loop() { } } -static void run(char *startup_cmd) { - pid_t startup_pid = -1; - - /* Add a Unix socket to the Wayland display. */ - const char *socket = wl_display_add_socket_auto(server.wl_display); - - if (!socket) - printf("startup: display_add_socket_auto\n"); - - /* Set the WAYLAND_DISPLAY environment variable to our socket and run the - * startup command if requested. */ +static void initialize_wayland_display(struct server *server) { + const char *socket = wl_display_add_socket_auto(server->wl_display); + if (!socket) { + fprintf(stderr, "startup: display_add_socket_auto failed\n"); + exit(EXIT_FAILURE); + } setenv("WAYLAND_DISPLAY", socket, 1); +} - /* Start the backend. This will enumerate outputs and inputs, become the DRM - * master, etc */ - if (!wlr_backend_start(server.backend)) { - printf("Failed to start backend"); - wlr_backend_destroy(server.backend); - return; +static void start_backend(struct server *server) { + if (!wlr_backend_start(server->backend)) { + fprintf(stderr, "Failed to start backend\n"); + wlr_backend_destroy(server->backend); + exit(EXIT_FAILURE); } +} - /* Now that outputs are initialized, choose initial selMon based on - * cursor position, and set default cursor image */ - update_monitor_geometries(); +static void initialize_cursor(struct server *server) { struct seat *seat = input_manager_get_default_seat(); struct cursor *cursor = seat->cursor; - struct monitor *m = - xy_to_monitor(cursor->wlr_cursor->x, cursor->wlr_cursor->y); + struct monitor *m = xy_to_monitor(cursor->wlr_cursor->x, cursor->wlr_cursor->y); focus_monitor(m); /* XXX hack to get cursor to display in its initial location (100, 100) * instead of (0, 0) and then jumping. still may not be fully * initialized, as the image/coordinates are not transformed for the * monitor when displayed here */ - wlr_cursor_warp_closest(seat->cursor->wlr_cursor, NULL, cursor->wlr_cursor->x, - cursor->wlr_cursor->y); - wlr_cursor_set_xcursor(cursor->wlr_cursor, seat->cursor->xcursor_mgr, - "left_ptr"); + wlr_cursor_warp_closest(seat->cursor->wlr_cursor, NULL, cursor->wlr_cursor->x, cursor->wlr_cursor->y); + wlr_cursor_set_xcursor(cursor->wlr_cursor, seat->cursor->xcursor_mgr, "left_ptr"); +} + +static pid_t execute_startup_command(const char *startup_cmd) { + pid_t pid = fork(); + if (pid == 0) { // Child process + execl("/bin/sh", "/bin/sh", "-c", startup_cmd, (void *)NULL); + fprintf(stderr, "Failed to execute startup command\n"); + exit(EXIT_FAILURE); + } + return pid; +} + +static void run(char *startup_cmd) { + pid_t startup_pid = -1; + + initialize_wayland_display(&server); + start_backend(&server); + update_monitor_geometries(); + initialize_cursor(&server); if (startup_cmd) { - startup_pid = fork(); - if (startup_pid == 0) { - execl("/bin/sh", "/bin/sh", "-c", startup_cmd, (void *)NULL); - } + startup_pid = execute_startup_command(startup_cmd); } run_event_loop(); From 0723ca1ba530acf48fc70c4047c22b60e5e7dca5 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Sun, 31 Dec 2023 15:05:03 +0100 Subject: [PATCH 32/37] refactor: refactor start_server --- src/server.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/server.c b/src/server.c index b387a57d..f73d3e95 100644 --- a/src/server.c +++ b/src/server.c @@ -538,12 +538,16 @@ int setup_server(struct server *server) } int start_server(char *startup_cmd) { - if (setup_server(&server)) { - printf("failed to setup japokwm\n"); + // Attempt to set up the server. If this fails, report the error and exit. + if (setup_server(&server) != 0) { + fprintf(stderr, "Failed to set up japokwm\n"); return EXIT_FAILURE; } + // Run the server with the provided startup command. + // This function contains the main event loop and will block until the server exits. run(startup_cmd); + return EXIT_SUCCESS; } From d48d263ce8f4f7a79c4e74bcf51f213566dfe678 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Sun, 31 Dec 2023 15:24:37 +0100 Subject: [PATCH 33/37] refactor: refactor setup_server --- src/server.c | 132 +++++++++++++++++++++++---------------------------- 1 file changed, 59 insertions(+), 73 deletions(-) diff --git a/src/server.c b/src/server.c index f73d3e95..57d5e8b1 100644 --- a/src/server.c +++ b/src/server.c @@ -42,7 +42,7 @@ struct server server; -static void init_event_handlers(struct server *server); +static void setup_event_handlers(struct server *server); static void init_lists(struct server *server); static void init_timers(struct server *server); static void init_lua_api(struct server *server); @@ -219,7 +219,7 @@ static void init_tablet_v2(struct server *server) { server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); } -static void init_event_handlers(struct server *server) +static void setup_event_handlers(struct server *server) { init_output_management(server); @@ -436,35 +436,17 @@ static void _async_handler_function(struct uv_async_s *arg) { free(data); } -int setup_server(struct server *server) -{ - server->uv_loop = uv_default_loop(); - - uv_async_init(uv_default_loop(), &server->async_handler, - _async_handler_function); - - /* If we don't provide a renderer, autocreate makes a GLES2 renderer for us. - * The renderer is responsible for defining the various pixel formats it - * supports for shared memory, this configures that for clients. */ - server->renderer = wlr_renderer_autocreate(server->backend); - - wlr_renderer_init_wl_display(server->renderer, server->wl_display); - - server->allocator = - wlr_allocator_autocreate(server->backend, server->renderer); - - /* This creates some hands-off wlroots interfaces. The compositor is - * necessary for clients to allocate surfaces and the data device manager - * handles the clipboard. Each of these wlroots interfaces has room for you - * to dig your fingers in and play with their behavior if you want. Note that - * the clients cannot set the selection directly without compositor approval, - * see the setsel() function. */ - +/* This creates some hands-off wlroots interfaces. The compositor is + * necessary for clients to allocate surfaces and the data device manager + * handles the clipboard. Each of these wlroots interfaces has room for you + * to dig your fingers in and play with their behavior if you want. Note that + * the clients cannot set the selection directly without compositor approval, + * see the setsel() function. */ +static void setup_wayland_interfaces(struct server *server) { server->compositor = wlr_compositor_create(server->wl_display, WL_COMPOSITOR_VERSION, server->renderer); wlr_subcompositor_create(server->wl_display); - wlr_export_dmabuf_manager_v1_create(server->wl_display); wlr_screencopy_manager_v1_create(server->wl_display); wlr_data_control_manager_v1_create(server->wl_display); @@ -472,53 +454,11 @@ int setup_server(struct server *server) wlr_gamma_control_manager_v1_create(server->wl_display); wlr_primary_selection_v1_device_manager_create(server->wl_display); wlr_viewporter_create(server->wl_display); - // TODO: do we still need that? - // wlr_idle_create(server->wl_display); wlr_idle_inhibit_v1_create(server->wl_display); - wlr_xdg_output_manager_v1_create(server->wl_display, server->output_layout); +} - /* Set up the xdg-shell. The xdg-shell is a - * Wayland protocol which is used for application windows. For more - * detail on shells, refer to the article: - * - * https://drewdevault.com/2018/07/29/Wayland-shells.html - */ - - server->input_inhibitor_mgr = - wlr_input_inhibit_manager_create(server->wl_display); - - /* setup virtual pointer manager*/ - server->virtual_pointer_mgr = - wlr_virtual_pointer_manager_v1_create(server->wl_display); - - /* setup virtual keyboard manager */ - server->virtual_keyboard_mgr = - wlr_virtual_keyboard_manager_v1_create(server->wl_display); - - /* setup relative pointer manager */ - server->relative_pointer_mgr = - wlr_relative_pointer_manager_v1_create(server->wl_display); - /* wl_signal_add(&server.virtual_keyboard_mgr->events.new_virtual_keyboard, - * &new_virtual_keyboard); */ - init_event_handlers(server); - - /* - * Configures a seat, which is a single "seat" at which a user sits and - * operates the computer. This conceptually includes up to one keyboard, - * pointer, touch, and drawing tablet device. We also rig up a listener to - * let us know when new input devices are available on the backend. - */ - server->input_manager = create_input_manager(); - struct seat *seat = create_seat("seat0"); - g_ptr_array_add(server->input_manager->seats, seat); - - server->output_mgr = wlr_output_manager_v1_create(server->wl_display); - wl_signal_add(&server->output_mgr->events.apply, &server->output_mgr_apply); - wl_signal_add(&server->output_mgr->events.test, &server->output_mgr_test); - - server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); - +static void setup_scene_graph(struct server *server) { server->scene = wlr_scene_create(); struct wlr_scene *server_scene = server->scene; server->scene_background = wlr_scene_tree_create(&server_scene->tree); @@ -526,17 +466,63 @@ int setup_server(struct server *server) server->scene_floating = wlr_scene_tree_create(&server_scene->tree); server->scene_popups = wlr_scene_tree_create(&server_scene->tree); server->scene_overlay = wlr_scene_tree_create(&server_scene->tree); +} - server->new_surface.notify = server_handle_new_surface; - wl_signal_add(&server->compositor->events.new_surface, &server->new_surface); +static void setup_input_managers(struct server *server) { + server->input_inhibitor_mgr = wlr_input_inhibit_manager_create(server->wl_display); + server->virtual_pointer_mgr = wlr_virtual_pointer_manager_v1_create(server->wl_display); + server->virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(server->wl_display); + server->relative_pointer_mgr = wlr_relative_pointer_manager_v1_create(server->wl_display); + // Uncomment and implement if necessary: + // wl_signal_add(&server->virtual_keyboard_mgr->events.new_virtual_keyboard, &new_virtual_keyboard); + server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); +} + +static void setup_output_management(struct server *server) { + server->output_mgr = wlr_output_manager_v1_create(server->wl_display); + wl_signal_add(&server->output_mgr->events.apply, &server->output_mgr_apply); + wl_signal_add(&server->output_mgr->events.test, &server->output_mgr_test); +} + + +static void initialize_renderer_and_allocator(struct server *server) { + server->renderer = wlr_renderer_autocreate(server->backend); + wlr_renderer_init_wl_display(server->renderer, server->wl_display); + server->allocator = wlr_allocator_autocreate(server->backend, server->renderer); +} + +static void setup_seat(struct server *server) { + server->input_manager = create_input_manager(); + struct seat *seat = create_seat("seat0"); + g_ptr_array_add(server->input_manager->seats, seat); #ifdef JAPOKWM_HAS_XWAYLAND init_xwayland(server->wl_display, seat); #endif +} + +static void setup_compositor_events(struct server *server) { + server->new_surface.notify = server_handle_new_surface; + wl_signal_add(&server->compositor->events.new_surface, &server->new_surface); +} + +int setup_server(struct server *server) { + server->uv_loop = uv_default_loop(); + uv_async_init(uv_default_loop(), &server->async_handler, _async_handler_function); + + initialize_renderer_and_allocator(server); + setup_wayland_interfaces(server); + setup_input_managers(server); + setup_event_handlers(server); + setup_seat(server); + setup_output_management(server); + setup_scene_graph(server); + setup_compositor_events(server); return 0; } + int start_server(char *startup_cmd) { // Attempt to set up the server. If this fails, report the error and exit. if (setup_server(&server) != 0) { From 2dc04002e63a94a4f0e4d9e41ef1f5f308b59fa0 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Sun, 31 Dec 2023 15:25:58 +0100 Subject: [PATCH 34/37] refactor: refactor server --- include/utils/coreUtils.h | 1 + src/server.c | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/utils/coreUtils.h b/include/utils/coreUtils.h index 633dca36..d1bb2877 100644 --- a/include/utils/coreUtils.h +++ b/include/utils/coreUtils.h @@ -45,6 +45,7 @@ typedef GPtrArray GPtrArray2D; // version management #define WL_COMPOSITOR_VERSION 6 #define LAYER_SHELL_VERSION 4 +#define XDG_SHELL_VERSION 2 #define foreach(item, array)\ for(int keep = 1, count = 0, size = LENGTH(array); keep && count < size; keep = 1, count++)\ diff --git a/src/server.c b/src/server.c index 57d5e8b1..b351f02d 100644 --- a/src/server.c +++ b/src/server.c @@ -38,8 +38,6 @@ #include "xdg_shell.h" #include "container.h" -#define XDG_SHELL_VERSION 2 - struct server server; static void setup_event_handlers(struct server *server); From 3124d924567b67f56ae01288df6113532cea515f Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Sun, 31 Dec 2023 15:26:55 +0100 Subject: [PATCH 35/37] refactor: delete dead code --- include/utils/coreUtils.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/utils/coreUtils.h b/include/utils/coreUtils.h index d1bb2877..3a027de8 100644 --- a/include/utils/coreUtils.h +++ b/include/utils/coreUtils.h @@ -47,10 +47,6 @@ typedef GPtrArray GPtrArray2D; #define LAYER_SHELL_VERSION 4 #define XDG_SHELL_VERSION 2 -#define foreach(item, array)\ - for(int keep = 1, count = 0, size = LENGTH(array); keep && count < size; keep = 1, count++)\ - for(item = array[count]; keep; keep = 0)\ - extern struct lua_State *L; bool dir_exists(const char *path); From 139a4eeff5a3a2d156ef087ad2a9250019bb134b Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Sun, 31 Dec 2023 15:29:43 +0100 Subject: [PATCH 36/37] refactor: add explaining comments --- include/utils/coreUtils.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/utils/coreUtils.h b/include/utils/coreUtils.h index 3a027de8..dfc4e84f 100644 --- a/include/utils/coreUtils.h +++ b/include/utils/coreUtils.h @@ -148,7 +148,9 @@ void *get_relative_item_in_composed_list(GPtrArray *arrays, int i, int j); int exec(const char *cmd); bool is_approx_equal(double a, double b, double error_range); +// Converts a Lua table index (1-based) to a C array index (0-based). int lua_idx_to_c_idx(int lua_idx); +// Converts a C array index (0-based) to a Lua table index (1-based). int c_idx_to_lua_idx(int c_idx); int scale_percent_to_integer(float percent); From fe8f84d5da0376ddb4518973c155b04e18a586f3 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Sun, 31 Dec 2023 15:31:27 +0100 Subject: [PATCH 37/37] refactor: remove dead code --- include/utils/coreUtils.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/utils/coreUtils.h b/include/utils/coreUtils.h index dfc4e84f..ba584910 100644 --- a/include/utils/coreUtils.h +++ b/include/utils/coreUtils.h @@ -21,9 +21,6 @@ typedef GPtrArray GPtrArray2D; /* macros */ //NOLINTNEXTLINE #define LENGTH(X) (sizeof X / sizeof X[0]) -#define END(A) ((A) + LENGTH(A)) -/* number of chars a string should contain */ -#define ARR_STRING_LENGTH(X) strlen(X) + 2*(strlen("[]") + NUM_DIGITS) // those constants are arbitrary and are bound to change #define MAXLEN 15