remove client-side decorations

This commit is contained in:
2026-01-04 18:07:28 +07:00
parent a36e205e08
commit 8995db6e1c
12 changed files with 163 additions and 30 deletions
+1 -1
View File
@@ -6,4 +6,4 @@ proto:
compile: proto
gcc -o absinthe src/* \
-I./ -I./include -DWLR_USE_UNSTABLE $(shell pkg-config wlroots-0.19 --libs --cflags) -lwayland-server -lxkbcommon \
-ggdb -Wall -Wextra
-ggdb
+1
View File
@@ -5,3 +5,4 @@
void output_frame(struct wl_listener *listener, void *data);
void output_request_state(struct wl_listener *listener, void *data);
void output_destroy(struct wl_listener *listener, void *data);
void output_layout_change(struct wl_listener *listener, void *data);
+1 -1
View File
@@ -5,8 +5,8 @@
void server_new_output(struct wl_listener *listener, void *data);
void server_new_xdg_toplevel(struct wl_listener *listener, void *data);
void server_new_xdg_popup(struct wl_listener *listener, void *data);
void server_new_xdg_decoration(struct wl_listener *listener, void *data);
void server_cursor_motion(struct wl_listener *listener, void *data);
void server_cursor_motion_absolute(struct wl_listener *listener, void *data);
+15 -4
View File
@@ -13,6 +13,8 @@
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_xdg_decoration_v1.h>
#define ABSINTHE_CURSOR_MOD WLR_MODIFIER_ALT
#define ABSINTHE_CURSOR_MOVE_BUTTON BTN_LEFT
@@ -36,6 +38,7 @@ struct absinthe_server {
struct wlr_backend *backend;
struct wlr_renderer *renderer;
struct wlr_allocator *allocator;
struct wlr_compositor *compositor;
struct wlr_scene *scene;
struct wlr_scene_output_layout *scene_layout;
@@ -43,6 +46,8 @@ struct absinthe_server {
struct wl_listener new_xdg_toplevel;
struct wl_listener new_xdg_popup;
struct wl_list toplevels;
struct wlr_xdg_decoration_manager_v1 *xdg_decoration_mgr;
struct wl_listener new_xdg_decoration;
struct wlr_cursor *cursor;
struct wlr_xcursor_manager *cursor_mgr;
@@ -60,14 +65,17 @@ struct absinthe_server {
struct wl_list keyboards;
enum absinthe_cursor_mode cursor_mode;
struct absinthe_toplevel *grabbed_toplevel;
uint32_t grabbed_toplevel_x, grabbed_toplevel_y;
uint32_t grabbed_toplevel_width, grabbed_toplevel_height;
struct wlr_box grabbed_box;
uint32_t grab_x, grab_y;
enum absinthe_cursor_resize_corner cursor_resize_corner;
struct wlr_output_layout *output_layout;
struct wl_list outputs;
struct wl_listener new_output;
struct wlr_output_layout *output_layout;
struct wl_listener output_layout_change;
struct wlr_output_manager_v1 *output_mgr;
struct wl_listener output_mgr_apply;
struct wl_listener output_mgr_test;
};
struct absinthe_output {
@@ -82,8 +90,8 @@ struct absinthe_output {
struct absinthe_toplevel {
struct wl_list link;
struct absinthe_server *server;
struct wlr_xdg_toplevel *xdg_toplevel;
struct wlr_scene_tree *scene_tree;
struct wlr_xdg_toplevel *xdg_toplevel;
struct wl_listener map;
struct wl_listener unmap;
struct wl_listener commit;
@@ -92,6 +100,9 @@ struct absinthe_toplevel {
struct wl_listener request_resize;
struct wl_listener request_maximize;
struct wl_listener request_fullscreen;
struct wlr_xdg_toplevel_decoration_v1 *decoration;
struct wl_listener decoration_request_mode;
struct wl_listener decoration_destroy;
};
struct absinthe_popup {
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include <wayland-server-core.h>
void xdg_decoration_request_mode(struct wl_listener *listener, void *data);
void xdg_decoration_destroy(struct wl_listener *listener, void *data);
+6 -6
View File
@@ -16,8 +16,8 @@ static void process_cursor_move(struct absinthe_server *server) {
if (!toplevel) return;
uint32_t new_x, new_y;
new_x = server->cursor->x - server->grab_x + server->grabbed_toplevel_x;
new_y = server->cursor->y - server->grab_y + server->grabbed_toplevel_y;
new_x = server->cursor->x - server->grab_x + server->grabbed_box.x;
new_y = server->cursor->y - server->grab_y + server->grabbed_box.y;
wlr_scene_node_set_position(&toplevel->scene_tree->node, new_x, new_y);
}
@@ -27,10 +27,10 @@ static void process_cursor_resize(struct absinthe_server *server) {
if (!toplevel) return;
int32_t new_x, new_y, new_width, new_height;
new_x = server->grabbed_toplevel_x;
new_y = server->grabbed_toplevel_y;
new_width = server->grabbed_toplevel_width;
new_height = server->grabbed_toplevel_height;
new_x = server->grabbed_box.x;
new_y = server->grabbed_box.y;
new_width = server->grabbed_box.width;
new_height = server->grabbed_box.height;
switch (server->cursor_resize_corner) {
case ABSINTHE_CURSOR_RESIZE_CORNER_TOP_LEFT:
+11
View File
@@ -1,4 +1,5 @@
#include <stdlib.h>
#include <unistd.h>
#include <wayland-server-core.h>
#include <xkbcommon/xkbcommon.h>
@@ -19,6 +20,16 @@ static bool keyboard_handle_keybind(struct absinthe_server *server, xkb_keysym_t
case XKB_KEY_Escape:
wl_display_terminate(server->display);
break;
case XKB_KEY_Q:
if (fork() == 0) {
execl("/bin/sh", "sh", "-c", "wofi --show drun", NULL);
}
break;
case XKB_KEY_Return:
if (fork() == 0) {
execl("/bin/sh", "sh", "-c", "alacritty", NULL);
}
break;
default:
return false;
}
+38 -2
View File
@@ -3,10 +3,23 @@
#include <wlr/types/wlr_subcompositor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/types/wlr_screencopy_v1.h>
#include <wlr/types/wlr_data_control_v1.h>
#include <wlr/types/wlr_viewporter.h>
#include <wlr/types/wlr_single_pixel_buffer_v1.h>
#include <wlr/types/wlr_fractional_scale_v1.h>
#include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_alpha_modifier_v1.h>
#include <wlr/types/wlr_export_dmabuf_v1.h>
#include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h>
#include <wlr/types/wlr_server_decoration.h>
#include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_xdg_output_v1.h>
#include "types.h"
#include "server.h"
#include "seat.h"
#include "output.h"
int main(int argc, char **argv)
{
@@ -40,16 +53,38 @@ int main(int argc, char **argv)
return 1;
}
wlr_compositor_create(server.display, 5, server.renderer);
server.compositor = wlr_compositor_create(server.display, 6, server.renderer);
wlr_subcompositor_create(server.display);
wlr_data_device_manager_create(server.display);
wlr_screencopy_manager_v1_create(server.display);
wlr_data_control_manager_v1_create(server.display);
wlr_viewporter_create(server.display);
wlr_single_pixel_buffer_manager_v1_create(server.display);
wlr_fractional_scale_manager_v1_create(server.display, 1);
wlr_presentation_create(server.display, server.backend, 2);
wlr_alpha_modifier_v1_create(server.display);
wlr_export_dmabuf_manager_v1_create(server.display);
wlr_ext_foreign_toplevel_list_v1_create(server.display, 1);
server.output_layout = wlr_output_layout_create(server.display);
wlr_server_decoration_manager_set_default_mode(
wlr_server_decoration_manager_create(server.display),
WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
server.xdg_decoration_mgr = wlr_xdg_decoration_manager_v1_create(server.display);
server.new_xdg_decoration.notify = server_new_xdg_decoration;
wl_signal_add(&server.xdg_decoration_mgr->events.new_toplevel_decoration, &server.new_xdg_decoration);
wl_list_init(&server.outputs);
server.new_output.notify = server_new_output;
wl_signal_add(&server.backend->events.new_output, &server.new_output);
server.output_layout = wlr_output_layout_create(server.display);
server.output_layout_change.notify = output_layout_change;
wl_signal_add(&server.output_layout->events.change, &server.output_layout_change);
server.output_mgr = wlr_output_manager_v1_create(server.display);
wlr_xdg_output_manager_v1_create(server.display, server.output_layout);
server.scene = wlr_scene_create();
server.scene_layout = wlr_scene_attach_output_layout(server.scene, server.output_layout);
@@ -111,6 +146,7 @@ int main(int argc, char **argv)
wl_list_remove(&server.new_xdg_toplevel.link);
wl_list_remove(&server.new_xdg_popup.link);
wl_list_remove(&server.new_xdg_decoration.link);
wl_list_remove(&server.cursor_motion.link);
wl_list_remove(&server.cursor_motion_absolute.link);
+23
View File
@@ -33,3 +33,26 @@ void output_destroy(struct wl_listener *listener, void *data)
wl_list_remove(&output->link);
free(output);
}
void output_layout_change(struct wl_listener *listener, void *data)
{
struct absinthe_server *server = wl_container_of(listener, server, output_layout_change);
struct wlr_output_configuration_v1 *config = wlr_output_configuration_v1_create();
struct wlr_output_configuration_head_v1 *config_head;
struct absinthe_output *output;
wl_list_for_each(output, &server->outputs, link) {
if (output->wlr_output->enabled) continue;
config_head = wlr_output_configuration_head_v1_create(config, output->wlr_output);
config_head->state.enabled = false;
wlr_output_layout_remove(server->output_layout, output->wlr_output);
}
wl_list_for_each(output, &server->outputs, link) {
if (!output->wlr_output->enabled || !wlr_output_layout_get(server->output_layout, output->wlr_output)) continue;
wlr_output_layout_add_auto(server->output_layout, output->wlr_output);
}
wlr_output_manager_v1_set_configuration(server->output_mgr, config);
}
+28 -7
View File
@@ -7,6 +7,7 @@
#include "output.h"
#include "xdg-toplevel.h"
#include "xdg-popup.h"
#include "xdg-decoration.h"
#include "absinthe-toplevel.h"
#include "focus.h"
#include "keyboard.h"
@@ -59,7 +60,7 @@ void server_new_xdg_toplevel(struct wl_listener *listener, void *data)
toplevel->xdg_toplevel = xdg_toplevel;
toplevel->scene_tree = wlr_scene_xdg_surface_create(&toplevel->server->scene->tree, xdg_toplevel->base);
toplevel->scene_tree->node.data = toplevel;
xdg_toplevel->base->data = toplevel->scene_tree;
xdg_toplevel->base->data = toplevel;
toplevel->map.notify = xdg_toplevel_map;
wl_signal_add(&xdg_toplevel->base->surface->events.map, &toplevel->map);
@@ -101,6 +102,20 @@ void server_new_xdg_popup(struct wl_listener *listener, void *data)
wl_signal_add(&xdg_popup->base->surface->events.destroy, &popup->destroy);
}
void server_new_xdg_decoration(struct wl_listener *listener, void *data)
{
struct wlr_xdg_toplevel_decoration_v1 *xdg_decoration = data;
struct absinthe_toplevel *toplevel = xdg_decoration->toplevel->base->data;
toplevel->decoration = xdg_decoration;
toplevel->decoration_request_mode.notify = xdg_decoration_request_mode;
wl_signal_add(&xdg_decoration->events.request_mode, &toplevel->decoration_request_mode);
toplevel->decoration_destroy.notify = xdg_decoration_destroy;
wl_signal_add(&xdg_decoration->events.destroy, &toplevel->decoration_destroy);
xdg_decoration_request_mode(&toplevel->decoration_request_mode, xdg_decoration);
}
void server_cursor_motion(struct wl_listener *listener, void *data)
{
struct absinthe_server *server = wl_container_of(listener, server, cursor_motion);
@@ -122,7 +137,7 @@ void server_cursor_button(struct wl_listener *listener, void *data)
struct absinthe_server *server = wl_container_of(listener, server, cursor_button);
struct wlr_pointer_button_event *event = data;
wlr_seat_pointer_notify_button(server->seat, event->time_msec, event->button, event->state);
bool handled = false;
if (event->state == WL_POINTER_BUTTON_STATE_RELEASED) {
reset_cursor_mode(server);
} else {
@@ -136,8 +151,10 @@ void server_cursor_button(struct wl_listener *listener, void *data)
if (mods & ABSINTHE_CURSOR_MOD) {
if (event->button == ABSINTHE_CURSOR_MOVE_BUTTON) {
server->cursor_mode = ABSINTHE_CURSOR_MOVE;
handled = true;
} else if (event->button == ABSINTHE_CURSOR_RESIZE_BUTTON) {
server->cursor_mode = ABSINTHE_CURSOR_RESIZE;
handled = true;
}
}
if (toplevel) {
@@ -146,11 +163,11 @@ void server_cursor_button(struct wl_listener *listener, void *data)
int lx, ly;
wlr_scene_node_coords(&toplevel->scene_tree->node, &lx, &ly);
server->grabbed_toplevel_x = lx;
server->grabbed_toplevel_y = ly;
server->grabbed_toplevel_width = toplevel->xdg_toplevel->base->geometry.width;
server->grabbed_toplevel_height = toplevel->xdg_toplevel->base->geometry.height;
wlr_log(WLR_DEBUG, "%d, %d", server->grabbed_toplevel_width, server->grabbed_toplevel_width);
server->grabbed_box.x = lx;
server->grabbed_box.y = ly;
server->grabbed_box.width = toplevel->xdg_toplevel->base->geometry.width;
server->grabbed_box.height = toplevel->xdg_toplevel->base->geometry.height;
wlr_log(WLR_DEBUG, "%d, %d", server->grabbed_box.width, server->grabbed_box.height);
server->grabbed_toplevel = toplevel;
int width = toplevel->xdg_toplevel->base->geometry.width;
@@ -167,6 +184,10 @@ void server_cursor_button(struct wl_listener *listener, void *data)
}
}
}
if (!handled) {
wlr_seat_pointer_notify_button(server->seat, event->time_msec, event->button, event->state);
}
}
void server_cursor_axis(struct wl_listener *listener, void *data)
+19
View File
@@ -0,0 +1,19 @@
#include <wayland-server-core.h>
#include "types.h"
void xdg_decoration_request_mode(struct wl_listener *listener, void *data)
{
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, decoration_request_mode);
if (toplevel->xdg_toplevel->base->initialized) {
wlr_xdg_toplevel_decoration_v1_set_mode(toplevel->decoration, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
}
}
void xdg_decoration_destroy(struct wl_listener *listener, void *data)
{
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, decoration_destroy);
wl_list_remove(&toplevel->decoration_request_mode.link);
wl_list_remove(&toplevel->decoration_destroy.link);
}
+14 -9
View File
@@ -3,6 +3,20 @@
#include <wayland-server-core.h>
#include "types.h"
#include "xdg-decoration.h"
void xdg_toplevel_commit(struct wl_listener *listener, void *data)
{
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, commit);
if (toplevel->xdg_toplevel->base->initial_commit) {
wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, 0, 0);
if (toplevel->decoration) {
xdg_decoration_request_mode(&toplevel->decoration_request_mode, toplevel->decoration);
}
}
}
void xdg_toplevel_map(struct wl_listener *listener, void *data)
{
@@ -18,15 +32,6 @@ void xdg_toplevel_unmap(struct wl_listener *listener, void *data)
wl_list_remove(&toplevel->link);
}
void xdg_toplevel_commit(struct wl_listener *listener, void *data)
{
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, commit);
if (toplevel->xdg_toplevel->base->initial_commit) {
wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, 0, 0);
}
}
void xdg_toplevel_destroy(struct wl_listener *listener, void *data)
{
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, destroy);