This commit is contained in:
2026-05-22 19:32:18 +07:00
parent 58ac1fb881
commit d34faf3469
16 changed files with 111 additions and 42 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: Never
ColumnLimit: 200
ColumnLimit: 120
AllowShortFunctionsOnASingleLine: false
SortIncludes: true
BreakBeforeBraces: Custom
+2 -1
View File
@@ -1,6 +1,7 @@
#include "types.h"
void client_from_coords(absn_server *server, double x, double y, struct wlr_surface **rsurface, absn_toplevel **rtoplevel, absn_layer_surface **rlayer_surface, double *rx, double *ry);
void client_from_coords(absn_server *server, double x, double y, struct wlr_surface **rsurface,
absn_toplevel **rtoplevel, absn_layer_surface **rlayer_surface, double *rx, double *ry);
void reset_cursor_mode(absn_server *server);
void process_cursor_motion(absn_server *server, uint32_t time);
+1
View File
@@ -4,6 +4,7 @@
#include "types.h"
bool toplevel_is_unmanaged(absn_toplevel *toplevel);
bool toplevel_wants_focus(absn_toplevel *toplevel);
void toplevel_get_geom(absn_toplevel *toplevel);
+7 -5
View File
@@ -28,10 +28,10 @@
#define MAX(A, B) (A) > (B) ? (A) : (B)
#define MIN(A, B) (A) < (B) ? (A) : (B)
/* macro for adding listener for event */
#define LISTEN(L, C, E) \
do { \
(L).notify = (C); \
wl_signal_add(&(E), &(L)); \
#define LISTEN(L, C, E) \
do { \
(L).notify = (C); \
wl_signal_add(&(E), &(L)); \
} while (0);
#define UNUSED(X) (void)(X)
#define CLEANMASK(M) (M & ~WLR_MODIFIER_CAPS)
@@ -51,7 +51,7 @@ enum {
BOTTOM_RIGHT,
};
/* toplevel types */
/* client types */
enum {
TOPLEVEL_XDG,
TOPLEVEL_X11,
@@ -218,6 +218,8 @@ struct absn_toplevel {
struct wlr_scene_rect *border[4];
struct wlr_xdg_toplevel_decoration_v1 *deco;
bool can_be_tiled;
bool floating;
bool fullscreen;
bool urgent;
+4 -2
View File
@@ -50,7 +50,8 @@ static int setup(absn_server *server)
server->scene = wlr_scene_create();
if (wlr_renderer_get_texture_formats(server->renderer, WLR_BUFFER_CAP_DMABUF)) {
wlr_drm_create(server->display, server->renderer);
wlr_scene_set_linux_dmabuf_v1(server->scene, wlr_linux_dmabuf_v1_create_with_renderer(server->display, 5, server->renderer));
wlr_scene_set_linux_dmabuf_v1(server->scene,
wlr_linux_dmabuf_v1_create_with_renderer(server->display, 5, server->renderer));
}
server->bg = wlr_scene_rect_create(&server->scene->tree, 0, 0, bgcolor);
@@ -74,7 +75,8 @@ static int setup(absn_server *server)
wlr_export_dmabuf_manager_v1_create(server->display);
wlr_ext_foreign_toplevel_list_v1_create(server->display, 1);
wlr_server_decoration_manager_set_default_mode(wlr_server_decoration_manager_create(server->display), WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
wlr_server_decoration_manager_set_default_mode(wlr_server_decoration_manager_create(server->display),
WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
server->xdg_deco_mgr = wlr_xdg_decoration_manager_v1_create(server->display);
LISTEN(server->new_xdg_deco, new_xdg_decoration, server->xdg_deco_mgr->events.new_toplevel_decoration);
+2 -1
View File
@@ -9,7 +9,8 @@
* returns surface at given cursor coordinates
* and coordinates inside of it to process input event
*/
void client_from_coords(absn_server *server, double x, double y, struct wlr_surface **rsurface, absn_toplevel **rtoplevel, absn_layer_surface **rlayer_surface, double *rx, double *ry)
void client_from_coords(absn_server *server, double x, double y, struct wlr_surface **rsurface,
absn_toplevel **rtoplevel, absn_layer_surface **rlayer_surface, double *rx, double *ry)
{
struct wlr_scene_node *pnode = NULL, *node = NULL;
struct wlr_scene_buffer *buffer = NULL;
+1 -1
View File
@@ -1,5 +1,5 @@
#include <stdnoreturn.h>
#include <stdlib.h>
#include <stdnoreturn.h>
#include <unistd.h>
#include <wayland-server-core.h>
#include <wlr/util/log.h>
+2 -1
View File
@@ -21,7 +21,8 @@ static bool handle_keybind(absn_server *server, uint32_t mods, xkb_keysym_t keys
{
int nkeyb = sizeof(keybinds) / sizeof(keybinds[0]);
for (int i = 0; i < nkeyb; ++i) {
if (CLEANMASK(keybinds[i].mods) == CLEANMASK(mods) && xkb_keysym_to_lower(keybinds[i].keysym) == xkb_keysym_to_lower(keysym)) {
if (CLEANMASK(keybinds[i].mods) == CLEANMASK(mods) &&
xkb_keysym_to_lower(keybinds[i].keysym) == xkb_keysym_to_lower(keysym)) {
keybinds[i].cb(server, &keybinds[i].arg);
return true;
}
+2 -1
View File
@@ -1,5 +1,5 @@
#include <wlr/types/wlr_layer_shell_v1.h>
#include <stdlib.h>
#include <wlr/types/wlr_layer_shell_v1.h>
#include "focus.h"
#include "layers.h"
@@ -54,6 +54,7 @@ void layer_surface_commit(struct wl_listener *listener, void *data)
}
layers_arrange(layer_surface->output);
wlr_surface_send_enter(surface->surface, surface->output);
}
void layer_surface_new_popup(struct wl_listener *listener, void *data)
+4 -2
View File
@@ -19,7 +19,8 @@ static void layer_arrange(absn_output *output, struct wl_list *list, struct wlr_
}
wlr_scene_layer_surface_v1_configure(layer_surface->scene_layer, &output->geom, usable_area);
wlr_scene_node_set_position(&layer_surface->popups->node, layer_surface->scene_tree->node.x, layer_surface->scene_tree->node.y);
wlr_scene_node_set_position(&layer_surface->popups->node, layer_surface->scene_tree->node.x,
layer_surface->scene_tree->node.y);
}
}
@@ -64,7 +65,8 @@ void layers_arrange(absn_output *output)
output->server->exclusive_focus = layer_surface;
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(output->server->seat);
if (keyboard) {
wlr_seat_keyboard_notify_enter(output->server->seat, layer_surface->wlr->surface, keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers);
wlr_seat_keyboard_notify_enter(output->server->seat, layer_surface->wlr->surface, keyboard->keycodes,
keyboard->num_keycodes, &keyboard->modifiers);
}
return;
}
+8 -4
View File
@@ -44,7 +44,8 @@ static void tile(struct absn_output *output)
break;
}
}
new_geom.x = output->usable_area.x + og, new_geom.y = output->usable_area.y + og, new_geom.width = output->usable_area.width - 2 * og, new_geom.height = output->usable_area.height - 2 * og,
new_geom.x = output->usable_area.x + og, new_geom.y = output->usable_area.y + og,
new_geom.width = output->usable_area.width - 2 * og, new_geom.height = output->usable_area.height - 2 * og,
toplevel_set_geom(toplevel, &new_geom);
return;
@@ -56,7 +57,8 @@ static void tile(struct absn_output *output)
int mcount = output->workspace->count;
float msize = output->workspace->size;
int32_t main_stack_width = (toplevels_count <= mcount) ? output->usable_area.width - 2 * og : msize * (output->usable_area.width - 2 * og);
int32_t main_stack_width =
(toplevels_count <= mcount) ? output->usable_area.width - 2 * og : msize * (output->usable_area.width - 2 * og);
int32_t w = output->usable_area.width - main_stack_width - 2 * og - lg;
int32_t pure_h;
@@ -163,7 +165,8 @@ static void tile_left(struct absn_output *output)
break;
}
}
new_geom.x = output->usable_area.x + og, new_geom.y = output->usable_area.y + og, new_geom.width = output->usable_area.width - 2 * og, new_geom.height = output->usable_area.height - 2 * og,
new_geom.x = output->usable_area.x + og, new_geom.y = output->usable_area.y + og,
new_geom.width = output->usable_area.width - 2 * og, new_geom.height = output->usable_area.height - 2 * og,
toplevel_set_geom(toplevel, &new_geom);
return;
@@ -175,7 +178,8 @@ static void tile_left(struct absn_output *output)
int mcount = output->workspace->count;
float msize = output->workspace->size;
int32_t main_stack_width = (toplevels_count <= mcount) ? output->usable_area.width - 2 * og : msize * (output->usable_area.width - 2 * og);
int32_t main_stack_width =
(toplevels_count <= mcount) ? output->usable_area.width - 2 * og : msize * (output->usable_area.width - 2 * og);
int32_t w = output->usable_area.width - main_stack_width - 2 * og - lg;
int32_t pure_h;
+2 -1
View File
@@ -17,12 +17,13 @@ void output_frame(struct wl_listener *listener, void *data)
absn_toplevel *toplevel;
wl_list_for_each(toplevel, &output->server->toplevels, link)
{
if (toplevel->resizing && toplevel->output == output) {
if (toplevel->resizing && !toplevel->floating && toplevel->output == output) {
goto skip;
}
}
wlr_scene_output_commit(scene_output, NULL);
skip:
clock_gettime(CLOCK_MONOTONIC, &now);
wlr_scene_output_send_frame_done(scene_output, &now);
+4 -2
View File
@@ -156,7 +156,8 @@ void new_layer_surface(struct wl_listener *listener, void *data)
struct wlr_scene_tree *scene_layer = server->layers[layermap[surface->pending.layer]];
layer_surface->scene_layer = wlr_scene_layer_surface_v1_create(scene_layer, surface);
layer_surface->scene_tree = layer_surface->scene_layer->tree;
layer_surface->popups = wlr_scene_tree_create(surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP ? server->layers[LAYER_TOP] : scene_layer);
layer_surface->popups = wlr_scene_tree_create(
surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP ? server->layers[LAYER_TOP] : scene_layer);
wl_list_insert(&layer_surface->output->layers[surface->pending.layer], &layer_surface->link);
wlr_surface_send_enter(surface->surface, surface->output);
@@ -300,7 +301,8 @@ void cursor_axis(struct wl_listener *listener, void *data)
{
absn_server *server = wl_container_of(listener, server, cursor_axis);
struct wlr_pointer_axis_event *event = data;
wlr_seat_pointer_notify_axis(server->seat, event->time_msec, event->orientation, event->delta, event->delta_discrete, event->source, event->relative_direction);
wlr_seat_pointer_notify_axis(server->seat, event->time_msec, event->orientation, event->delta,
event->delta_discrete, event->source, event->relative_direction);
}
void cursor_frame(struct wl_listener *listener, void *data)
+42 -15
View File
@@ -17,10 +17,20 @@ void toplevel_map(struct wl_listener *listener, void *data)
toplevel->scene_tree->node.data = toplevel;
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, toplevel_is_unmanaged(toplevel));
if (toplevel->type != TOPLEVEL_X11 && wl_resource_get_version(toplevel->xdg->resource) >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) {
update_focused_output(toplevel->server);
toplevel->output = toplevel->server->focused_output;
toplevel->workspace = toplevel->output->workspace;
toplevel->fullscreen = false;
#ifdef XWAYLAND
if (toplevel->type == TOPLEVEL_X11) {
toplevel->xw->surface->data = toplevel;
}
#endif
if (toplevel->type != TOPLEVEL_X11 &&
wl_resource_get_version(toplevel->xdg->resource) >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) {
wlr_xdg_toplevel_set_tiled(toplevel->xdg, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
} else {
wlr_xdg_toplevel_set_maximized(toplevel->xdg, true);
}
#ifdef XWAYLAND
@@ -36,27 +46,42 @@ void toplevel_map(struct wl_listener *listener, void *data)
toplevel_get_geom(toplevel);
toplevel->bw = toplevel_is_unmanaged(toplevel) ? 0 : TOPLEVEL_BW;
#ifdef XWAYLAND
if (toplevel->type == TOPLEVEL_X11) {
toplevel->xw->surface->data = toplevel;
if (toplevel_is_unmanaged(toplevel)) {
toplevel_set_floating(toplevel, true);
toplevel_set_size(toplevel, toplevel->geom.width, toplevel->geom.height);
if (toplevel_wants_focus(toplevel)) {
focus_toplevel(toplevel);
server->exclusive_focus = toplevel;
}
goto unset_fullscreen;
}
#endif
for (int i = 0; i < 4; ++i) {
toplevel->border[i] = wlr_scene_rect_create(toplevel->scene_tree, 0, 0, unfocused_bc);
toplevel->border[i]->node.data = toplevel;
}
update_focused_output(toplevel->server);
toplevel->output = toplevel->server->focused_output;
toplevel->workspace = toplevel->output->workspace;
toplevel->fullscreen = false;
wl_list_insert(&toplevel->server->toplevels, &toplevel->link);
wl_list_insert(&toplevel->server->focus_stack, &toplevel->flink);
layout_arrange(toplevel->output);
focus_toplevel(focus_get_topmost(toplevel->server));
if (toplevel->type == TOPLEVEL_XDG && toplevel->xdg->parent) {
toplevel->floating = 1;
} else if (toplevel->type == TOPLEVEL_X11 && toplevel->xw->parent) {
toplevel->floating = 1;
}
unset_fullscreen:
absn_toplevel *t;
wl_list_for_each(t, &server->toplevels, link)
{
if (t->workspace == toplevel->workspace && t->fullscreen) {
toplevel_set_fullscreen(t, false);
}
}
layout_arrange(toplevel->output);
}
void toplevel_unmap(struct wl_listener *listener, void *data)
@@ -73,8 +98,10 @@ void toplevel_unmap(struct wl_listener *listener, void *data)
toplevel->server->exclusive_focus = NULL;
}
wl_list_remove(&toplevel->link);
wl_list_remove(&toplevel->flink);
if (!toplevel_is_unmanaged(toplevel)) {
wl_list_remove(&toplevel->link);
wl_list_remove(&toplevel->flink);
}
layout_arrange(toplevel->output);
focus_toplevel(focus_get_topmost(toplevel->server));
+18 -4
View File
@@ -22,6 +22,14 @@ bool toplevel_is_unmanaged(absn_toplevel *toplevel)
return false;
}
bool toplevel_wants_focus(absn_toplevel *toplevel)
{
#ifdef XWAYLAND
return toplevel_is_unmanaged(toplevel) && wlr_xwayland_surface_override_redirect_wants_focus(toplevel->xw) &&
wlr_xwayland_surface_icccm_input_model(toplevel->xw) != WLR_ICCCM_INPUT_MODEL_NONE;
#endif
}
/* used only to get initial window size */
void toplevel_get_geom(absn_toplevel *toplevel)
{
@@ -69,7 +77,8 @@ void toplevel_set_pos(absn_toplevel *toplevel, int32_t x, int32_t y)
void toplevel_set_size(absn_toplevel *toplevel, int32_t width, int32_t height)
{
if (width <= 2 * toplevel->bw || height <= 2 * toplevel->bw || (width == toplevel->geom.width && height == toplevel->geom.height)) {
if (width <= 2 * toplevel->bw || height <= 2 * toplevel->bw ||
(width == toplevel->geom.width && height == toplevel->geom.height)) {
return;
}
toplevel->geom.width = width;
@@ -94,13 +103,14 @@ void toplevel_set_size(absn_toplevel *toplevel, int32_t width, int32_t height)
}
#ifdef XWAYLAND
else if (toplevel->type == TOPLEVEL_X11) {
wlr_xwayland_surface_configure(toplevel->xw, toplevel->geom.x, toplevel->geom.y, width - 2 * bw, height - 2 * toplevel->bw);
wlr_xwayland_surface_configure(toplevel->xw, toplevel->geom.x, toplevel->geom.y, width - 2 * bw,
height - 2 * toplevel->bw);
/* manually update position */
toplevel_set_pos(toplevel, toplevel->geom.x, toplevel->geom.y);
} else
}
#endif
wlr_scene_subsurface_tree_set_clip(&toplevel->scene_surface->node, &clip);
wlr_scene_subsurface_tree_set_clip(&toplevel->scene_surface->node, &clip);
}
void toplevel_set_geom(absn_toplevel *toplevel, struct wlr_box *geom)
@@ -115,6 +125,10 @@ void toplevel_set_floating(absn_toplevel *toplevel, bool floating)
return;
}
if (floating && !toplevel->can_be_tiled) {
return;
}
toplevel->floating = floating;
if (floating) {
+11 -1
View File
@@ -1,5 +1,6 @@
#ifdef XWAYLAND
#include "config.h"
#include "xwayland.h"
#include "toplevel-handlers.h"
#include "toplevel.h"
@@ -53,7 +54,16 @@ void xwayland_configure(struct wl_listener *listener, void *data)
void xwayland_set_hints(struct wl_listener *listener, void *data)
{
UNUSED(listener);
UNUSED(data);
absn_toplevel *toplevel = wl_container_of(listener, toplevel, xw_set_hints);
if (toplevel == toplevel->server->focused_toplevel || !toplevel->xw->hints) {
return;
}
toplevel->urgent = xcb_icccm_wm_hints_get_urgency(toplevel->xw->hints);
struct wlr_surface *surface = toplevel->xw->surface;
if (toplevel->urgent && surface && surface->mapped) {
toplevel_set_border_color(toplevel, urgent_bc);
}
}
#endif