layer shell and others

This commit is contained in:
2026-05-17 20:03:02 +07:00
parent 62dbb3a54e
commit 5d81826183
26 changed files with 3616 additions and 298 deletions
+1 -1
View File
@@ -2,9 +2,9 @@ BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: Never
ColumnLimit: 120
AllowShortFunctionsOnASingleLine: false
SortIncludes: true
InsertBraces: true
BreakBeforeBraces: Custom
BraceWrapping:
AfterFunction: true
+2916
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -3,7 +3,6 @@
#include <wayland-server-core.h>
void layer_surface_map(struct wl_listener *listener, void *data);
void layer_surface_unmap(struct wl_listener *listener, void *data);
void layer_surface_commit(struct wl_listener *listener, void *data);
void layer_surface_new_popup(struct wl_listener *listener, void *data);
+1 -1
View File
@@ -4,6 +4,6 @@
#include "output.h"
#include "types.h"
void layer_arrange(absn_output *output);
void layers_arrange(absn_output *output);
#endif
+1
View File
@@ -11,5 +11,6 @@ void output_destroy(struct wl_listener *listener, void *data);
void output_layout_change(struct wl_listener *listener, void *data);
void update_focused_output(absn_server *server);
void output_arrange(absn_output *output);
#endif
+2 -1
View File
@@ -3,7 +3,8 @@
#include "types.h"
absn_toplevel *toplevel_at(absn_server *server, double lx, double ly, struct wlr_surface **surface, double *sx,
absn_toplevel *toplevel_at(absn_server *server, double lx, double ly,
struct wlr_surface **surface, double *sx,
double *sy);
bool toplevel_is_unmanaged(absn_toplevel *toplevel);
+10 -4
View File
@@ -74,7 +74,7 @@ static const int layermap[] = {
LAYER_BACKGROUND,
LAYER_BOTTOM,
LAYER_TOP,
LAYER_FULLSCREEN,
LAYER_OVERLAY,
};
enum {
@@ -150,6 +150,8 @@ typedef struct {
struct wl_list focus_stack;
absn_toplevel *focused_toplevel;
void *exclusive_focus;
absn_output *focused_output;
struct wl_list outputs;
struct wl_listener new_output;
@@ -177,7 +179,7 @@ struct absn_output {
struct wl_listener request_state;
struct wl_listener destroy;
struct wl_list layer_surfaces;
struct wl_list layers[4];
};
typedef struct {
@@ -186,9 +188,10 @@ typedef struct {
absn_server *server;
absn_output *output;
int type; /* LAYER_SURFACE */
bool mapped;
struct wlr_scene_tree *scene_tree;
struct wlr_scene_layer_surface_v1 *scene_layer;
struct wlr_scene_tree *popups;
struct wlr_layer_surface_v1 *wlr;
struct wl_listener map;
@@ -249,8 +252,11 @@ struct absn_toplevel {
typedef struct {
struct wlr_xdg_popup *wlr;
int parent_type;
void *parent;
struct wl_listener commit;
struct wl_listener destroy;
} absn_popup;
typedef struct {
+2 -5
View File
@@ -1,9 +1,6 @@
#ifndef __XDG_POPUP_H_
#define __XDG_POPUP_H_
#include <wayland-server-core.h>
#ifndef __XDG_POPUP_H
#define __XDG_POPUP_H
void xdg_popup_commit(struct wl_listener *listener, void *data);
void xdg_popup_destroy(struct wl_listener *listener, void *data);
#endif
+46 -24
View File
@@ -33,7 +33,8 @@ static int setup(absn_server *server)
return 1;
}
server->backend = wlr_backend_autocreate(wl_display_get_event_loop(server->display), NULL);
server->backend = wlr_backend_autocreate(
wl_display_get_event_loop(server->display), NULL);
if (!server->backend) {
wlr_log(WLR_ERROR, "Failed to create wlr_backend");
return 1;
@@ -48,21 +49,25 @@ static int setup(absn_server *server)
wlr_renderer_init_wl_shm(server->renderer, server->display);
server->scene = wlr_scene_create();
if (wlr_renderer_get_texture_formats(server->renderer, WLR_BUFFER_CAP_DMABUF)) {
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);
server->allocator = wlr_allocator_autocreate(server->backend, server->renderer);
server->allocator =
wlr_allocator_autocreate(server->backend, server->renderer);
if (!server->allocator) {
wlr_log(WLR_ERROR, "Failed to create wlr_allocator");
return 1;
}
/* wlroots managers */
server->compositor = wlr_compositor_create(server->display, 6, 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);
@@ -75,10 +80,13 @@ 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_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);
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);
/* toplevels lists */
wl_list_init(&server->toplevels);
@@ -89,18 +97,22 @@ static int setup(absn_server *server)
LISTEN(server->new_output, new_output, server->backend->events.new_output);
server->output_layout = wlr_output_layout_create(server->display);
LISTEN(server->layout_change, output_layout_change, server->output_layout->events.change);
LISTEN(server->layout_change, output_layout_change,
server->output_layout->events.change);
server->output_mgr = wlr_output_manager_v1_create(server->display);
wlr_xdg_output_manager_v1_create(server->display, server->output_layout);
server->scene_layout = wlr_scene_attach_output_layout(server->scene, server->output_layout);
server->scene_layout =
wlr_scene_attach_output_layout(server->scene, server->output_layout);
/* xdg_shell */
server->xdg_shell = wlr_xdg_shell_create(server->display, 6);
LISTEN(server->new_xdg_toplevel, new_xdg_toplevel, server->xdg_shell->events.new_toplevel);
LISTEN(server->new_xdg_popup, new_xdg_popup, server->xdg_shell->events.new_popup);
LISTEN(server->new_xdg_toplevel, new_xdg_toplevel,
server->xdg_shell->events.new_toplevel);
LISTEN(server->new_xdg_popup, new_xdg_popup,
server->xdg_shell->events.new_popup);
/* cursor */
server->cursor = wlr_cursor_create();
@@ -110,7 +122,8 @@ static int setup(absn_server *server)
server->cursor_mode = CURSOR_PASSTHROUGH;
LISTEN(server->cursor_motion, cursor_motion, server->cursor->events.motion);
LISTEN(server->cursor_motion_abs, cursor_motion_abs, server->cursor->events.motion_absolute);
LISTEN(server->cursor_motion_abs, cursor_motion_abs,
server->cursor->events.motion_absolute);
LISTEN(server->cursor_button, cursor_button, server->cursor->events.button);
LISTEN(server->cursor_axis, cursor_axis, server->cursor->events.axis);
LISTEN(server->cursor_frame, cursor_frame, server->cursor->events.frame);
@@ -119,14 +132,18 @@ static int setup(absn_server *server)
wl_list_init(&server->keyboards);
server->seat = wlr_seat_create(server->display, "seat0");
LISTEN(server->new_input, new_input, server->backend->events.new_input);
LISTEN(server->request_cursor, request_cursor, server->seat->events.request_set_cursor);
LISTEN(server->pointer_focus_change, pointer_focus_change, server->seat->pointer_state.events.focus_change);
LISTEN(server->request_set_selection, request_cursor, server->seat->events.request_set_selection);
LISTEN(server->request_cursor, request_cursor,
server->seat->events.request_set_cursor);
LISTEN(server->pointer_focus_change, pointer_focus_change,
server->seat->pointer_state.events.focus_change);
LISTEN(server->request_set_selection, request_cursor,
server->seat->events.request_set_selection);
/* layer shell */
server->layer_shell = wlr_layer_shell_v1_create(server->display, 1);
for (int i = 0; i < LAYERS_COUNT; ++i)
server->layer_shell = wlr_layer_shell_v1_create(server->display, 5);
for (int i = 0; i < LAYERS_COUNT; ++i) {
server->layers[i] = wlr_scene_tree_create(&server->scene->tree);
}
/* workspaces */
int workspaces_count = sizeof(workspaces) / sizeof(workspaces[0]);
@@ -142,12 +159,16 @@ static int setup(absn_server *server)
unsetenv("DISPLAY");
#ifdef XWAYLAND
if ((server->xwayland = wlr_xwayland_create(server->display, server->compositor, 1))) {
LISTEN(server->xw_ready, xwayland_ready, server->xwayland->events.ready);
LISTEN(server->xw_new_surface, xwayland_new_surface, server->xwayland->events.new_surface);
if ((server->xwayland =
wlr_xwayland_create(server->display, server->compositor, 1))) {
LISTEN(server->xw_ready, xwayland_ready,
server->xwayland->events.ready);
LISTEN(server->xw_new_surface, xwayland_new_surface,
server->xwayland->events.new_surface);
setenv("DISPLAY", server->xwayland->display_name, 1);
wlr_log(WLR_INFO, "Running XWayland, DISPLAY=%s", server->xwayland->display_name);
wlr_log(WLR_INFO, "Running XWayland, DISPLAY=%s",
server->xwayland->display_name);
} else {
wlr_log(WLR_ERROR, "Failed to setup XWayland, continuing without it");
}
@@ -209,8 +230,9 @@ int main(void)
{
absn_server server = {0};
int err = setup(&server);
if (err)
if (err) {
return EXIT_FAILURE;
}
wl_display_run(server.display);
cleanup(&server);
return EXIT_SUCCESS;
+22 -11
View File
@@ -18,8 +18,9 @@ static void process_cursor_move(absn_server *server)
{
struct absn_toplevel *toplevel = server->focused_toplevel;
if (!toplevel)
if (!toplevel) {
return;
}
if (toplevel->fullscreen) {
toplevel->prev_geom = toplevel->geom;
@@ -31,9 +32,10 @@ static void process_cursor_move(absn_server *server)
new_y = server->cursor->y - server->grab_y + server->grab_geom.y;
toplevel_set_pos(toplevel, new_x, new_y);
if (!toplevel->floating)
if (!toplevel->floating) {
toplevel_set_floating(toplevel, true);
}
}
static void apply_resize(absn_toplevel *toplevel, struct wlr_box *new_geom)
{
@@ -44,18 +46,21 @@ static void apply_resize(absn_toplevel *toplevel, struct wlr_box *new_geom)
int32_t max_width = toplevel->xdg->current.max_width;
int32_t max_height = toplevel->xdg->current.max_height;
if (max_width == 0)
if (max_width == 0) {
max_width = 10000;
}
if (max_height == 0)
if (max_height == 0) {
max_height = 10000;
}
if (!(new_geom->width >= min_width && new_geom->width <= max_width)) {
new_geom->width = toplevel->geom.width;
new_geom->x = toplevel->geom.x;
}
if (!(new_geom->height >= min_height && new_geom->height <= max_height)) {
if (!(new_geom->height >= min_height &&
new_geom->height <= max_height)) {
new_geom->height = toplevel->geom.height;
new_geom->y = toplevel->geom.y;
}
@@ -68,17 +73,21 @@ static void process_cursor_resize(absn_server *server)
{
struct absn_toplevel *toplevel = server->focused_toplevel;
if (!toplevel)
if (!toplevel) {
return;
}
if (toplevel->resizing)
if (toplevel->resizing) {
return;
}
if (toplevel->fullscreen)
if (toplevel->fullscreen) {
toplevel_set_fullscreen(toplevel, false);
}
if (!toplevel->floating)
if (!toplevel->floating) {
toplevel_set_floating(toplevel, true);
}
int32_t new_x, new_y, new_width, new_height;
new_x = server->grab_geom.x;
@@ -89,8 +98,9 @@ static void process_cursor_resize(absn_server *server)
int32_t dx = server->cursor->x - server->grab_x;
int32_t dy = server->cursor->y - server->grab_y;
if (dx == 0 && dy == 0)
if (dx == 0 && dy == 0) {
return;
}
switch (server->resize_corner) {
case TOP_LEFT:
@@ -133,7 +143,8 @@ void process_cursor_motion(absn_server *server, uint32_t time)
{
double sx, sy;
struct wlr_surface *surface = NULL;
toplevel_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
toplevel_at(server, server->cursor->x, server->cursor->y, &surface, &sx,
&sy);
struct wlr_seat *seat = server->seat;
if (server->cursor_mode == CURSOR_MOVE) {
+22 -11
View File
@@ -8,35 +8,40 @@
void unfocus_toplevel(absn_toplevel *toplevel)
{
if (!toplevel)
if (!toplevel) {
return;
}
if (toplevel->type == TOPLEVEL_XDG)
if (toplevel->type == TOPLEVEL_XDG) {
wlr_xdg_toplevel_set_activated(toplevel->xdg, false);
}
toplevel_set_border_color(toplevel, unfocused_bc);
}
void focus_toplevel(absn_toplevel *toplevel)
{
if (!toplevel)
if (!toplevel) {
return;
}
absn_server *server = toplevel->server;
struct wlr_seat *seat = server->seat;
struct wlr_surface *prev_surface = seat->keyboard_state.focused_surface;
struct wlr_surface *surface;
#ifdef XWAYLAND
if (toplevel->type == TOPLEVEL_X11)
if (toplevel->type == TOPLEVEL_X11) {
surface = toplevel->xw->surface;
else
} else
#endif
surface = toplevel->xdg->base->surface;
if (surface == prev_surface)
if (surface == prev_surface) {
return;
}
if (prev_surface)
if (prev_surface) {
unfocus_toplevel(prev_surface->data);
}
toplevel->server->focused_toplevel = toplevel;
@@ -44,12 +49,16 @@ void focus_toplevel(absn_toplevel *toplevel)
wlr_scene_node_raise_to_top(&toplevel->scene_tree->node);
wl_list_remove(&toplevel->flink);
wl_list_insert(&server->focus_stack, &toplevel->flink);
if (toplevel->type != TOPLEVEL_X11)
if (toplevel->type != TOPLEVEL_X11) {
wlr_xdg_toplevel_set_activated(toplevel->xdg, true);
}
toplevel_set_border_color(toplevel, focused_bc);
if (keyboard)
wlr_seat_keyboard_notify_enter(seat, surface, keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers);
if (keyboard) {
wlr_seat_keyboard_notify_enter(seat, surface, keyboard->keycodes,
keyboard->num_keycodes,
&keyboard->modifiers);
}
}
/*
@@ -61,8 +70,10 @@ absn_toplevel *focus_get_topmost(absn_server *server)
absn_toplevel *toplevel;
wl_list_for_each(toplevel, &server->focus_stack, flink)
{
if (toplevel && toplevel->workspace == server->focused_output->workspace)
if (toplevel &&
toplevel->workspace == server->focused_output->workspace) {
return toplevel;
}
}
return NULL;
}
+63 -28
View File
@@ -21,8 +21,9 @@ void run(absn_server *server, const absn_arg *arg)
void kill_focus(absn_server *server, const absn_arg *arg)
{
UNUSED(arg);
if (!server->focused_toplevel)
if (!server->focused_toplevel) {
return;
}
absn_toplevel *focus = server->focused_toplevel;
@@ -39,23 +40,26 @@ void kill_focus(absn_server *server, const absn_arg *arg)
void cycle_focus(absn_server *server, const absn_arg *arg)
{
absn_toplevel *toplevel = focus_get_topmost(server);
if (!toplevel || toplevel->fullscreen)
if (!toplevel || toplevel->fullscreen) {
return;
}
absn_toplevel *new_focus;
if (arg->i > 0) {
wl_list_for_each(new_focus, &toplevel->link, link)
{
if (toplevel->workspace == new_focus->workspace)
if (toplevel->workspace == new_focus->workspace) {
break;
}
}
} else {
wl_list_for_each_reverse(new_focus, &toplevel->link, link)
{
if (toplevel->workspace == new_focus->workspace)
if (toplevel->workspace == new_focus->workspace) {
break;
}
}
}
focus_toplevel(new_focus);
}
@@ -63,8 +67,9 @@ void swap_focus(absn_server *server, const absn_arg *arg)
{
absn_toplevel *toplevel = focus_get_topmost(server);
if (!toplevel || toplevel->fullscreen || toplevel->floating)
if (!toplevel || toplevel->fullscreen || toplevel->floating) {
return;
}
absn_toplevel *temp = NULL;
absn_toplevel *first = NULL;
@@ -72,14 +77,17 @@ void swap_focus(absn_server *server, const absn_arg *arg)
wl_list_for_each(temp, &server->toplevels, link)
{
if (temp->workspace == toplevel->workspace)
if (temp->workspace == toplevel->workspace) {
last = temp;
if (!first && temp->workspace == toplevel->workspace)
}
if (!first && temp->workspace == toplevel->workspace) {
first = temp;
}
}
if (first == last)
if (first == last) {
return;
}
absn_toplevel *swap = NULL;
if (arg->i > 0) {
@@ -91,9 +99,10 @@ void swap_focus(absn_server *server, const absn_arg *arg)
wl_list_for_each(swap, &toplevel->link, link)
{
if (toplevel->workspace == swap->workspace)
if (toplevel->workspace == swap->workspace) {
break;
}
}
wl_list_remove(&toplevel->link);
wl_list_insert(&swap->link, &toplevel->link);
@@ -106,9 +115,10 @@ void swap_focus(absn_server *server, const absn_arg *arg)
wl_list_for_each_reverse(swap, &toplevel->link, link)
{
if (toplevel->workspace == swap->workspace)
if (toplevel->workspace == swap->workspace) {
break;
}
}
wl_list_remove(&swap->link);
wl_list_insert(&toplevel->link, &swap->link);
@@ -121,8 +131,9 @@ arrange:
void toggle_fullscreen(absn_server *server, const absn_arg *arg)
{
UNUSED(arg);
if (!server->focused_toplevel)
if (!server->focused_toplevel) {
return;
}
absn_toplevel *focus = server->focused_toplevel;
toplevel_set_fullscreen(focus, !focus->fullscreen);
@@ -131,19 +142,30 @@ void toggle_fullscreen(absn_server *server, const absn_arg *arg)
void toggle_floating(absn_server *server, const absn_arg *arg)
{
UNUSED(arg);
if (!server->focused_toplevel)
if (!server->focused_toplevel) {
return;
}
absn_toplevel *focus = server->focused_toplevel;
toplevel_set_floating(focus, !focus->floating);
if (focus->floating) {
int32_t new_x = focus->output->geom.x +
(focus->output->geom.width / 2 - focus->geom.width / 2);
int32_t new_y =
focus->output->geom.y +
(focus->output->geom.height / 2 - focus->geom.height / 2);
toplevel_set_pos(focus, new_x, new_y);
}
}
void increase_master_width(absn_server *server, const absn_arg *arg)
{
absn_workspace *workspace = server->focused_output->workspace;
if (workspace->size + arg->f >= 1.0 || workspace->size + arg->f <= 0.0)
if (workspace->size + arg->f >= 1.0 || workspace->size + arg->f <= 0.0) {
return;
}
workspace->size += arg->f;
layout_arrange(workspace->output);
@@ -153,8 +175,9 @@ void increase_master_count(absn_server *server, const absn_arg *arg)
{
absn_workspace *workspace = server->focused_output->workspace;
if (workspace->count + arg->i <= 0)
if (workspace->count + arg->i <= 0) {
return;
}
workspace->count += arg->i;
layout_arrange(workspace->output);
@@ -164,23 +187,27 @@ void switch_workspace(absn_server *server, const absn_arg *arg)
{
int i;
for (i = 0; i < server->workspaces_count; ++i) {
if (arg->v == server->workspaces[i].name)
if (arg->v == server->workspaces[i].name) {
break; /* found it */
}
}
if (&server->workspaces[i] == server->focused_output->workspace)
if (&server->workspaces[i] == server->focused_output->workspace) {
return;
}
int toplevels_count = 0;
absn_toplevel *toplevel;
wl_list_for_each(toplevel, &server->toplevels, link)
{
if (toplevel->workspace == server->focused_output->workspace)
if (toplevel->workspace == server->focused_output->workspace) {
toplevels_count++;
}
}
if (toplevels_count == 0)
if (toplevels_count == 0) {
server->focused_output->workspace->output = NULL;
}
if (!server->workspaces[i].output) {
server->workspaces[i].output = server->focused_output;
@@ -201,11 +228,13 @@ void switch_workspace(absn_server *server, const absn_arg *arg)
absn_toplevel *focus = NULL;
wl_list_for_each(toplevel, &server->toplevels, link)
{
if (!focus && toplevel && toplevel->workspace == &server->workspaces[i]) {
if (!focus && toplevel &&
toplevel->workspace == &server->workspaces[i]) {
focus = toplevel; /* found it */
}
if (toplevel && toplevel->workspace == &server->workspaces[i] && toplevel->fullscreen) {
if (toplevel && toplevel->workspace == &server->workspaces[i] &&
toplevel->fullscreen) {
/* overwrite if there is a fullscreen window */
focus = toplevel;
break;
@@ -217,14 +246,15 @@ void switch_workspace(absn_server *server, const absn_arg *arg)
/* crazy way to make toplevel focus properly if it was focused before */
struct wlr_surface *surface;
#ifdef XWAYLAND
if (focus->type == TOPLEVEL_X11)
if (focus->type == TOPLEVEL_X11) {
surface = focus->xw->surface;
else
} else
#endif
surface = focus->xdg->base->surface;
if (surface == server->seat->keyboard_state.focused_surface)
if (surface == server->seat->keyboard_state.focused_surface) {
server->seat->keyboard_state.focused_surface = NULL;
}
focus_toplevel(focus);
}
@@ -234,23 +264,28 @@ void switch_workspace(absn_server *server, const absn_arg *arg)
void move_focus_to_workspace(absn_server *server, const absn_arg *arg)
{
if (!server->focused_toplevel)
if (!server->focused_toplevel) {
return;
}
if (server->focused_toplevel->fullscreen)
if (server->focused_toplevel->fullscreen) {
toplevel_set_fullscreen(server->focused_toplevel, false);
}
int i;
for (i = 0; i < server->workspaces_count; ++i) {
if (arg->v == server->workspaces[i].name)
if (arg->v == server->workspaces[i].name) {
break; /* found it */
}
}
if (&server->workspaces[i] == server->focused_toplevel->workspace)
if (&server->workspaces[i] == server->focused_toplevel->workspace) {
return;
}
if (!server->workspaces[i].output)
if (!server->workspaces[i].output) {
server->workspaces[i].output = server->focused_output;
}
server->focused_toplevel->output = server->workspaces[i].output;
server->focused_toplevel->workspace = &server->workspaces[i];
+12 -6
View File
@@ -14,15 +14,18 @@ void handle_modifiers(struct wl_listener *listener, void *data)
absn_keyboard *keyboard = wl_container_of(listener, keyboard, modifiers);
wlr_seat_set_keyboard(keyboard->server->seat, keyboard->wlr);
wlr_seat_keyboard_notify_modifiers(keyboard->server->seat, &keyboard->wlr->modifiers);
wlr_seat_keyboard_notify_modifiers(keyboard->server->seat,
&keyboard->wlr->modifiers);
}
static bool handle_keybind(absn_server *server, uint32_t mods, xkb_keysym_t keysym)
static bool handle_keybind(absn_server *server, uint32_t mods,
xkb_keysym_t keysym)
{
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)) {
xkb_keysym_to_lower(keybinds[i].keysym) ==
xkb_keysym_to_lower(keysym)) {
keybinds[i].cb(server, &keybinds[i].arg);
return true;
}
@@ -44,15 +47,18 @@ void handle_key(struct wl_listener *listener, void *data)
bool handled = false;
if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
for (int i = 0; i < nsyms; ++i) {
handled = handle_keybind(keyboard->server, mods, syms[i]) || handled;
handled =
handle_keybind(keyboard->server, mods, syms[i]) || handled;
}
}
if (handled)
if (handled) {
return;
}
wlr_seat_set_keyboard(keyboard->server->seat, keyboard->wlr);
wlr_seat_keyboard_notify_key(keyboard->server->seat, event->time_msec, event->keycode, event->state);
wlr_seat_keyboard_notify_key(keyboard->server->seat, event->time_msec,
event->keycode, event->state);
}
void handle_destroy(struct wl_listener *listener, void *data)
+61 -14
View File
@@ -1,45 +1,92 @@
#include <wlr/types/wlr_layer_shell_v1.h>
#include "focus.h"
#include "layer.h"
#include "layers.h"
#include "types.h"
void layer_surface_map(struct wl_listener *listener, void *data)
{
UNUSED(listener);
UNUSED(data);
}
#include "xdg-popup.h"
void layer_surface_unmap(struct wl_listener *listener, void *data)
{
UNUSED(data);
absn_layer_surface *layer_surface = wl_container_of(listener, layer_surface, unmap);
absn_layer_surface *layer_surface =
wl_container_of(listener, layer_surface, unmap);
if (layer_surface->wlr->surface == layer_surface->server->seat->keyboard_state.focused_surface)
if (layer_surface->wlr->surface ==
layer_surface->server->seat->keyboard_state.focused_surface) {
focus_toplevel(focus_get_topmost(layer_surface->server));
}
if (layer_surface == layer_surface->server->exclusive_focus) {
layer_surface->server->exclusive_focus = NULL;
}
layer_surface->mapped = false;
}
void layer_surface_commit(struct wl_listener *listener, void *data)
{
UNUSED(data);
absn_layer_surface *layer_surface = wl_container_of(listener, layer_surface, commit);
absn_layer_surface *layer_surface =
wl_container_of(listener, layer_surface, commit);
struct wlr_layer_surface_v1 *surface = layer_surface->wlr;
struct wlr_scene_tree *scene_layer =
layer_surface->server->layers[layermap[surface->current.layer]];
wlr_layer_surface_v1_configure(surface, surface->pending.desired_width, surface->pending.desired_height);
if (surface->initial_commit) {
struct wlr_layer_surface_v1_state old_state = surface->current;
surface->current = surface->pending;
layers_arrange(layer_surface->output);
surface->current = old_state;
return;
}
layer_arrange(layer_surface->output);
if (surface->current.committed == 0 ||
layer_surface->mapped == surface->surface->mapped) {
return;
}
layer_surface->mapped = surface->surface->mapped;
if (scene_layer != layer_surface->scene_tree->node.parent) {
wlr_scene_node_reparent(&layer_surface->scene_tree->node, scene_layer);
wl_list_remove(&layer_surface->link);
wl_list_insert(&layer_surface->output->layers[surface->current.layer],
&layer_surface->link);
bool on_top_layer =
surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP;
if (on_top_layer) {
wlr_scene_node_reparent(
&layer_surface->popups->node,
layer_surface->output->server->layers[LAYER_TOP]);
} else {
wlr_scene_node_reparent(&layer_surface->popups->node, scene_layer);
}
}
layers_arrange(layer_surface->output);
}
void layer_surface_new_popup(struct wl_listener *listener, void *data)
{
UNUSED(listener);
UNUSED(data);
absn_layer_surface *layer_surface =
wl_container_of(listener, layer_surface, new_popup);
struct wlr_xdg_popup *xdg_popup = data;
wlr_scene_xdg_surface_create(layer_surface->popups, xdg_popup->base);
absn_popup *popup = calloc(1, sizeof(*popup));
popup->wlr = xdg_popup;
popup->parent_type = LAYER_SURFACE;
popup->parent = layer_surface;
LISTEN(popup->commit, xdg_popup_commit,
xdg_popup->base->surface->events.commit);
}
void layer_surface_destroy(struct wl_listener *listener, void *data)
{
UNUSED(data);
absn_layer_surface *layer_surface = wl_container_of(listener, layer_surface, destroy);
absn_layer_surface *layer_surface =
wl_container_of(listener, layer_surface, destroy);
wl_list_remove(&layer_surface->link);
wl_list_remove(&layer_surface->map.link);
-21
View File
@@ -1,21 +0,0 @@
#include <wlr/types/wlr_layer_shell_v1.h>
#include "layout.h"
#include "types.h"
void layer_arrange(absn_output *output)
{
struct wlr_box usable_area = output->geom;
absn_layer_surface *layer_surface;
wl_list_for_each(layer_surface, &output->layer_surfaces, link)
{
if (!layer_surface->wlr->initialized)
continue;
wlr_scene_layer_surface_v1_configure(layer_surface->scene_layer, &output->geom, &usable_area);
}
output->usable_area = usable_area;
layout_arrange(output);
}
+87
View File
@@ -0,0 +1,87 @@
#include <wlr/types/wlr_layer_shell_v1.h>
#include "focus.h"
#include "layout.h"
#include "output.h"
#include "types.h"
/* arrange layers logic from dwl */
static void layer_arrange(absn_output *output, struct wl_list *list,
struct wlr_box *usable_area, int exclusive)
{
absn_layer_surface *layer_surface;
wl_list_for_each(layer_surface, list, link)
{
struct wlr_layer_surface_v1 *surface = layer_surface->wlr;
if (!surface->initialized) {
continue;
}
if (exclusive != (surface->current.exclusive_zone > 0)) {
continue;
}
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);
}
}
void layers_arrange(absn_output *output)
{
if (!output->wlr->enabled) {
return;
}
struct wlr_box usable_area = output->usable_area;
/* Arrange non-exclusive surfaces from top->bottom */
for (int i = 3; i >= 0; --i) {
layer_arrange(output, &output->layers[i], &usable_area, 1);
}
if (!wlr_box_equal(&output->usable_area, &usable_area)) {
output->usable_area = usable_area;
output_arrange(output);
}
/* Arrange non-exclusive surfaces from top->bottom */
for (int i = 3; i >= 0; --i) {
layer_arrange(output, &output->layers[i], &usable_area, 0);
}
uint32_t layers_above_shell[] = {
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
ZWLR_LAYER_SHELL_V1_LAYER_TOP,
};
int layers_above_shell_count =
sizeof(layers_above_shell) / sizeof(layers_above_shell[0]);
absn_layer_surface *layer_surface;
for (int i = 0; i < layers_above_shell_count; ++i) {
wl_list_for_each_reverse(layer_surface,
&output->layers[layers_above_shell[i]], link)
{
if (!layer_surface->wlr->current.keyboard_interactive ||
!layer_surface->mapped) {
continue;
}
unfocus_toplevel(output->server->focused_toplevel);
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);
}
return;
}
}
}
+53 -22
View File
@@ -14,9 +14,11 @@ static int prepare_output(struct absn_output *output)
{
if (toplevel->workspace == output->workspace) {
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, true);
if (!toplevel->floating && !toplevel->fullscreen)
if (!toplevel->floating && !toplevel->fullscreen) {
res++;
} else if (toplevel->output == output && toplevel->workspace != output->workspace) {
}
} else if (toplevel->output == output &&
toplevel->workspace != output->workspace) {
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, false);
}
}
@@ -28,8 +30,9 @@ static void tile(struct absn_output *output)
{
int toplevels_count = prepare_output(output);
if (toplevels_count < 1)
if (toplevels_count < 1) {
return;
}
int32_t og = OUTPUT_GAP;
struct wlr_box new_geom;
@@ -38,11 +41,15 @@ static void tile(struct absn_output *output)
if (toplevels_count == 1) {
wl_list_for_each(toplevel, &output->server->toplevels, link)
{
if (toplevel->workspace == output->workspace && !toplevel->floating && !toplevel->fullscreen)
if (toplevel->workspace == output->workspace &&
!toplevel->floating && !toplevel->fullscreen) {
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;
@@ -55,7 +62,9 @@ static void tile(struct absn_output *output)
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);
(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;
@@ -74,8 +83,10 @@ static void tile(struct absn_output *output)
wl_list_for_each(toplevel, &output->server->toplevels, link)
{
if (toplevel->workspace != output->workspace || toplevel->floating || toplevel->fullscreen)
if (toplevel->workspace != output->workspace ||
toplevel->floating || toplevel->fullscreen) {
continue;
}
cur_h = h + (i < r ? 1 : 0);
@@ -95,8 +106,10 @@ static void tile(struct absn_output *output)
wl_list_for_each(toplevel, &output->server->toplevels, link)
{
if (toplevel->workspace != output->workspace || toplevel->floating || toplevel->fullscreen)
if (toplevel->workspace != output->workspace || toplevel->floating ||
toplevel->fullscreen) {
continue;
}
if (i < mcount) {
total_lg = (mcount - 1) * lg;
@@ -115,8 +128,9 @@ static void tile(struct absn_output *output)
dy += cur_h + lg;
} else {
if (i == mcount)
if (i == mcount) {
dy = og;
}
int32_t stack_count = toplevels_count - mcount;
total_lg = (stack_count - 1) * lg;
@@ -144,8 +158,9 @@ static void tile_left(struct absn_output *output)
{
int toplevels_count = prepare_output(output);
if (toplevels_count < 1)
if (toplevels_count < 1) {
return;
}
int32_t og = OUTPUT_GAP;
struct wlr_box new_geom;
@@ -154,11 +169,15 @@ static void tile_left(struct absn_output *output)
if (toplevels_count == 1) {
wl_list_for_each(toplevel, &output->server->toplevels, link)
{
if (toplevel->workspace == output->workspace && !toplevel->floating && !toplevel->fullscreen)
if (toplevel->workspace == output->workspace &&
!toplevel->floating && !toplevel->fullscreen) {
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;
@@ -171,7 +190,9 @@ static void tile_left(struct absn_output *output)
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);
(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;
@@ -190,8 +211,10 @@ static void tile_left(struct absn_output *output)
wl_list_for_each(toplevel, &output->server->toplevels, link)
{
if (toplevel->workspace != output->workspace || toplevel->floating || toplevel->fullscreen)
if (toplevel->workspace != output->workspace ||
toplevel->floating || toplevel->fullscreen) {
continue;
}
cur_h = h + (i < r ? 1 : 0);
@@ -211,8 +234,10 @@ static void tile_left(struct absn_output *output)
wl_list_for_each(toplevel, &output->server->toplevels, link)
{
if (toplevel->workspace != output->workspace || toplevel->floating || toplevel->fullscreen)
if (toplevel->workspace != output->workspace || toplevel->floating ||
toplevel->fullscreen) {
continue;
}
if (i < mcount) {
total_lg = (mcount - 1) * lg;
@@ -222,7 +247,8 @@ static void tile_left(struct absn_output *output)
cur_h = h + (i < r ? 1 : 0);
new_geom.x = output->usable_area.x + output->usable_area.width - og - main_stack_width;
new_geom.x = output->usable_area.x + output->usable_area.width -
og - main_stack_width;
new_geom.y = output->usable_area.y + dy;
new_geom.width = main_stack_width;
new_geom.height = cur_h;
@@ -231,8 +257,9 @@ static void tile_left(struct absn_output *output)
dy += cur_h + lg;
} else {
if (i == mcount)
if (i == mcount) {
dy = og;
}
int32_t stack_count = toplevels_count - mcount;
total_lg = (stack_count - 1) * lg;
@@ -260,8 +287,9 @@ static void monocle(struct absn_output *output)
{
int toplevels_count = prepare_output(output);
if (toplevels_count < 1)
if (toplevels_count < 1) {
return;
}
int32_t og = OUTPUT_GAP;
@@ -275,8 +303,10 @@ static void monocle(struct absn_output *output)
absn_toplevel *toplevel;
wl_list_for_each(toplevel, &output->server->toplevels, link)
{
if (toplevel->workspace != output->workspace || toplevel->floating || toplevel->fullscreen)
if (toplevel->workspace != output->workspace || toplevel->floating ||
toplevel->fullscreen) {
continue;
}
toplevel_set_geom(toplevel, &new_geom);
}
@@ -284,8 +314,9 @@ static void monocle(struct absn_output *output)
void layout_arrange(struct absn_output *output)
{
if (!output)
if (!output) {
return;
}
switch (output->workspace->layout) {
case LAYOUT_TILE:
+66 -18
View File
@@ -17,9 +17,10 @@ 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->output == output) {
goto skip;
}
}
wlr_scene_output_commit(scene_output, NULL);
skip:
@@ -29,7 +30,8 @@ skip:
void output_request_state(struct wl_listener *listener, void *data)
{
struct absn_output *output = wl_container_of(listener, output, request_state);
struct absn_output *output =
wl_container_of(listener, output, request_state);
const struct wlr_output_event_request_state *event = data;
wlr_output_commit_state(output->wlr, event->state);
}
@@ -37,7 +39,8 @@ void output_request_state(struct wl_listener *listener, void *data)
void output_destroy(struct wl_listener *listener, void *data)
{
UNUSED(data);
struct absn_output *output = wl_container_of(listener, output, request_state);
struct absn_output *output =
wl_container_of(listener, output, request_state);
wl_list_remove(&output->frame.link);
wl_list_remove(&output->request_state.link);
@@ -50,7 +53,8 @@ void output_layout_change(struct wl_listener *listener, void *data)
{
UNUSED(data);
absn_server *server = wl_container_of(listener, server, layout_change);
struct wlr_output_configuration_v1 *config = wlr_output_configuration_v1_create();
struct wlr_output_configuration_v1 *config =
wlr_output_configuration_v1_create();
absn_toplevel *toplevel = NULL;
absn_output *output;
@@ -58,46 +62,58 @@ void output_layout_change(struct wl_listener *listener, void *data)
wl_list_for_each(output, &server->outputs, link)
{
if (output->wlr->enabled)
if (output->wlr->enabled) {
continue;
config_head = wlr_output_configuration_head_v1_create(config, output->wlr);
}
config_head =
wlr_output_configuration_head_v1_create(config, output->wlr);
config_head->state.enabled = 0;
wlr_output_layout_remove(server->output_layout, output->wlr);
// closemon(m);
// m->m = m->w = (struct wlr_box){0};
output->geom = output->usable_area = (struct wlr_box){0};
}
wl_list_for_each(output, &server->outputs, link)
{
if (output->wlr->enabled && !wlr_output_layout_get(server->output_layout, output->wlr))
wlr_output_layout_add_auto(server->output_layout, toplevel->output->wlr);
if (output->wlr->enabled &&
!wlr_output_layout_get(server->output_layout, output->wlr)) {
wlr_output_layout_add_auto(server->output_layout,
toplevel->output->wlr);
}
}
struct wlr_box layout_geom;
wlr_output_layout_get_box(server->output_layout, NULL, &layout_geom);
wlr_scene_node_set_position(&server->bg->node, layout_geom.x, layout_geom.y);
wlr_scene_node_set_position(&server->bg->node, layout_geom.x,
layout_geom.y);
wlr_scene_rect_set_size(server->bg, layout_geom.width, layout_geom.height);
wl_list_for_each(output, &server->outputs, link)
{
if (!output->wlr->enabled)
if (!output->wlr->enabled) {
continue;
config_head = wlr_output_configuration_head_v1_create(config, output->wlr);
}
config_head =
wlr_output_configuration_head_v1_create(config, output->wlr);
wlr_output_layout_get_box(server->output_layout, output->wlr, &output->geom);
wlr_output_layout_get_box(server->output_layout, output->wlr,
&output->geom);
output->usable_area = output->geom;
if ((toplevel = focus_get_topmost(server)) && toplevel->fullscreen)
toplevel_set_size(toplevel, output->geom.width, output->geom.height);
if ((toplevel = focus_get_topmost(server)) && toplevel->fullscreen) {
toplevel_set_size(toplevel, output->geom.width,
output->geom.height);
}
config_head->state.x = output->geom.x;
config_head->state.y = output->geom.y;
if (!server->focused_output)
if (!server->focused_output) {
server->focused_output = output;
}
}
if (server->focused_output && server->focused_output->wlr->enabled) {
wl_list_for_each(toplevel, &server->toplevels, link)
@@ -121,11 +137,43 @@ void update_focused_output(absn_server *server)
int32_t cursor_y = server->cursor->y;
wl_list_for_each(output, &server->outputs, link)
{
bool cursor_in_output_x = cursor_x >= output->geom.x && cursor_x <= output->geom.x + output->geom.width;
bool cursor_in_output_y = cursor_y >= output->geom.y && cursor_y <= output->geom.y + output->geom.height;
bool cursor_in_output_x =
cursor_x >= output->geom.x &&
cursor_x <= output->geom.x + output->geom.width;
bool cursor_in_output_y =
cursor_y >= output->geom.y &&
cursor_y <= output->geom.y + output->geom.height;
if (cursor_in_output_x && cursor_in_output_y) {
server->focused_output = output;
break;
}
}
}
void output_arrange(absn_output *output)
{
if (!output->wlr->enabled) {
return;
}
absn_server *server = output->server;
bool enabled;
absn_toplevel *toplevel;
wl_list_for_each(toplevel, &server->toplevels, link)
{
if (toplevel->output == output) {
enabled = output->workspace == toplevel->workspace;
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, enabled);
}
}
wl_list_for_each(toplevel, &server->toplevels, link)
{
if (toplevel->output != output ||
toplevel->scene_tree->node.parent ==
server->layers[LAYER_FULLSCREEN]) {
continue;
}
wlr_scene_node_reparent(&toplevel->scene_tree->node,
toplevel->scene_tree->node.parent);
}
}
+10 -5
View File
@@ -9,22 +9,27 @@ void request_cursor(struct wl_listener *listener, void *data)
struct wlr_seat_pointer_request_set_cursor_event *event = data;
struct wlr_seat_client *client = server->seat->pointer_state.focused_client;
if (client == event->seat_client)
wlr_cursor_set_surface(server->cursor, event->surface, event->hotspot_x, event->hotspot_y);
if (client == event->seat_client) {
wlr_cursor_set_surface(server->cursor, event->surface, event->hotspot_x,
event->hotspot_y);
}
}
void pointer_focus_change(struct wl_listener *listener, void *data)
{
absn_server *server = wl_container_of(listener, server, pointer_focus_change);
absn_server *server =
wl_container_of(listener, server, pointer_focus_change);
struct wlr_seat_pointer_focus_change_event *event = data;
if (!event->new_surface)
if (!event->new_surface) {
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "default");
}
}
void request_set_selection(struct wl_listener *listener, void *data)
{
absn_server *server = wl_container_of(listener, server, request_set_selection);
absn_server *server =
wl_container_of(listener, server, request_set_selection);
struct wlr_seat_request_set_selection_event *event = data;
wlr_seat_set_selection(server->seat, event->source, event->serial);
+121 -58
View File
@@ -9,6 +9,7 @@
#include "focus.h"
#include "keyboard.h"
#include "layer-surface.h"
#include "layers.h"
#include "output.h"
#include "toplevel-handlers.h"
#include "toplevel.h"
@@ -35,8 +36,9 @@ void new_output(struct wl_listener *listener, void *data)
wlr_output_state_set_enabled(&state, true);
struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
if (mode)
if (mode) {
wlr_output_state_set_mode(&state, mode);
}
wlr_output_commit_state(wlr_output, &state);
wlr_output_state_finish(&state);
@@ -54,17 +56,24 @@ void new_output(struct wl_listener *listener, void *data)
}
LISTEN(output->frame, output_frame, wlr_output->events.frame);
LISTEN(output->request_state, output_request_state, wlr_output->events.request_state);
LISTEN(output->request_state, output_request_state,
wlr_output->events.request_state);
LISTEN(output->destroy, output_destroy, wlr_output->events.destroy);
wl_list_insert(&server->outputs, &output->link);
wl_list_init(&output->layer_surfaces);
for (int i = 0; i < 4; ++i) {
wl_list_init(&output->layers[i]);
}
struct wlr_output_layout_output *l_layout = wlr_output_layout_add_auto(server->output_layout, output->wlr);
struct wlr_scene_output *scene_output = wlr_scene_output_create(server->scene, wlr_output);
wlr_scene_output_layout_add_output(server->scene_layout, l_layout, scene_output);
wlr_output_layout_get_box(server->output_layout, output->wlr, &output->geom);
struct wlr_output_layout_output *l_layout =
wlr_output_layout_add_auto(server->output_layout, output->wlr);
struct wlr_scene_output *scene_output =
wlr_scene_output_create(server->scene, wlr_output);
wlr_scene_output_layout_add_output(server->scene_layout, l_layout,
scene_output);
wlr_output_layout_get_box(server->output_layout, output->wlr,
&output->geom);
output->usable_area = output->geom;
}
@@ -82,14 +91,21 @@ void new_xdg_toplevel(struct wl_listener *listener, void *data)
wlr_surface_set_preferred_buffer_scale(toplevel->xdg->base->surface, 1);
LISTEN(toplevel->commit, toplevel_commit, xdg_toplevel->base->surface->events.commit);
LISTEN(toplevel->map, toplevel_map, xdg_toplevel->base->surface->events.map);
LISTEN(toplevel->unmap, toplevel_unmap, xdg_toplevel->base->surface->events.unmap);
LISTEN(toplevel->commit, toplevel_commit,
xdg_toplevel->base->surface->events.commit);
LISTEN(toplevel->map, toplevel_map,
xdg_toplevel->base->surface->events.map);
LISTEN(toplevel->unmap, toplevel_unmap,
xdg_toplevel->base->surface->events.unmap);
LISTEN(toplevel->destroy, toplevel_destroy, xdg_toplevel->events.destroy);
LISTEN(toplevel->request_move, toplevel_request_move, xdg_toplevel->events.request_move);
LISTEN(toplevel->request_resize, toplevel_request_resize, xdg_toplevel->events.request_resize);
LISTEN(toplevel->request_maximize, toplevel_request_maximize, xdg_toplevel->events.request_maximize);
LISTEN(toplevel->request_fullscreen, toplevel_request_fullscreen, xdg_toplevel->events.request_fullscreen);
LISTEN(toplevel->request_move, toplevel_request_move,
xdg_toplevel->events.request_move);
LISTEN(toplevel->request_resize, toplevel_request_resize,
xdg_toplevel->events.request_resize);
LISTEN(toplevel->request_maximize, toplevel_request_maximize,
xdg_toplevel->events.request_maximize);
LISTEN(toplevel->request_fullscreen, toplevel_request_fullscreen,
xdg_toplevel->events.request_fullscreen);
}
void new_xdg_popup(struct wl_listener *listener, void *data)
@@ -97,16 +113,22 @@ void new_xdg_popup(struct wl_listener *listener, void *data)
absn_server *server = wl_container_of(listener, server, new_xdg_popup);
struct wlr_xdg_popup *xdg_popup = data;
struct wlr_xdg_surface *parent =
wlr_xdg_surface_try_from_wlr_surface(xdg_popup->parent);
if (!parent) {
return;
}
absn_toplevel *toplevel = parent->data;
wlr_scene_xdg_surface_create(toplevel->scene_tree, xdg_popup->base);
absn_popup *popup = calloc(1, sizeof(*popup));
popup->wlr = xdg_popup;
popup->parent_type = TOPLEVEL_XDG;
popup->parent = toplevel;
struct wlr_xdg_surface *parent = wlr_xdg_surface_try_from_wlr_surface(xdg_popup->parent);
absn_toplevel *parent_toplevel = parent->data;
struct wlr_scene_tree *parent_tree = parent_toplevel->scene_tree;
xdg_popup->base->data = wlr_scene_xdg_surface_create(parent_tree, xdg_popup->base);
LISTEN(popup->commit, xdg_popup_commit, xdg_popup->base->surface->events.commit);
LISTEN(popup->destroy, xdg_popup_destroy, xdg_popup->base->surface->events.destroy);
LISTEN(popup->commit, xdg_popup_commit,
xdg_popup->base->surface->events.commit);
}
void new_xdg_decoration(struct wl_listener *listener, void *data)
@@ -116,7 +138,8 @@ void new_xdg_decoration(struct wl_listener *listener, void *data)
absn_toplevel *toplevel = deco->toplevel->base->data;
toplevel->deco = deco;
LISTEN(toplevel->deco_request_mode, deco_request_mode, deco->events.request_mode);
LISTEN(toplevel->deco_request_mode, deco_request_mode,
deco->events.request_mode);
LISTEN(toplevel->deco_destroy, deco_destroy, deco->events.destroy);
/* Forse server side decoration mode */
@@ -135,20 +158,31 @@ void new_layer_surface(struct wl_listener *listener, void *data)
absn_layer_surface *layer_surface = calloc(1, sizeof(*layer_surface));
LISTEN(layer_surface->map, layer_surface_map, surface->surface->events.map);
LISTEN(layer_surface->unmap, layer_surface_unmap, surface->surface->events.unmap);
LISTEN(layer_surface->commit, layer_surface_commit, surface->surface->events.commit);
LISTEN(layer_surface->new_popup, layer_surface_new_popup, surface->events.new_popup);
LISTEN(layer_surface->destroy, layer_surface_destroy, surface->surface->events.destroy);
LISTEN(layer_surface->unmap, layer_surface_unmap,
surface->surface->events.unmap);
LISTEN(layer_surface->commit, layer_surface_commit,
surface->surface->events.commit);
LISTEN(layer_surface->new_popup, layer_surface_new_popup,
surface->events.new_popup);
LISTEN(layer_surface->destroy, layer_surface_destroy,
surface->surface->events.destroy);
layer_surface->wlr = surface;
layer_surface->output = surface->output->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);
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;
wl_list_insert(&layer_surface->output->layer_surfaces, &layer_surface->link);
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);
}
@@ -161,9 +195,13 @@ void xwayland_ready(struct wl_listener *listener, void *data)
wlr_xwayland_set_seat(server->xwayland, server->seat);
struct wlr_xcursor *xcursor;
if ((xcursor = wlr_xcursor_manager_get_xcursor(server->cursor_mgr, "default", 1))) {
struct wlr_buffer *buffer = wlr_xcursor_image_get_buffer(xcursor->images[0]);
wlr_xwayland_set_cursor(server->xwayland, buffer, xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y);
if ((xcursor = wlr_xcursor_manager_get_xcursor(server->cursor_mgr,
"default", 1))) {
struct wlr_buffer *buffer =
wlr_xcursor_image_get_buffer(xcursor->images[0]);
wlr_xwayland_set_cursor(server->xwayland, buffer,
xcursor->images[0]->hotspot_x,
xcursor->images[0]->hotspot_y);
}
}
@@ -180,14 +218,21 @@ void xwayland_new_surface(struct wl_listener *listener, void *data)
surface->data = toplevel;
LISTEN(toplevel->destroy, toplevel_destroy, surface->events.destroy);
LISTEN(toplevel->request_maximize, toplevel_request_maximize, surface->events.request_maximize);
LISTEN(toplevel->request_fullscreen, toplevel_request_fullscreen, surface->events.request_fullscreen);
LISTEN(toplevel->request_maximize, toplevel_request_maximize,
surface->events.request_maximize);
LISTEN(toplevel->request_fullscreen, toplevel_request_fullscreen,
surface->events.request_fullscreen);
LISTEN(toplevel->xw_activate, xwayland_activate, surface->events.request_activate);
LISTEN(toplevel->xw_associate, xwayland_associate, surface->events.associate);
LISTEN(toplevel->xw_dissociate, xwayland_dissociate, surface->events.dissociate);
LISTEN(toplevel->xw_configure, xwayland_configure, surface->events.request_configure);
LISTEN(toplevel->xw_set_hints, xwayland_set_hints, surface->events.set_hints);
LISTEN(toplevel->xw_activate, xwayland_activate,
surface->events.request_activate);
LISTEN(toplevel->xw_associate, xwayland_associate,
surface->events.associate);
LISTEN(toplevel->xw_dissociate, xwayland_dissociate,
surface->events.dissociate);
LISTEN(toplevel->xw_configure, xwayland_configure,
surface->events.request_configure);
LISTEN(toplevel->xw_set_hints, xwayland_set_hints,
surface->events.set_hints);
}
#endif
@@ -196,7 +241,8 @@ void cursor_motion(struct wl_listener *listener, void *data)
absn_server *server = wl_container_of(listener, server, cursor_motion);
struct wlr_pointer_motion_event *event = data;
update_focused_output(server);
wlr_cursor_move(server->cursor, &event->pointer->base, event->delta_x, event->delta_y);
wlr_cursor_move(server->cursor, &event->pointer->base, event->delta_x,
event->delta_y);
process_cursor_motion(server, event->time_msec);
}
@@ -205,7 +251,8 @@ void cursor_motion_abs(struct wl_listener *listener, void *data)
absn_server *server = wl_container_of(listener, server, cursor_motion_abs);
struct wlr_pointer_motion_absolute_event *event = data;
update_focused_output(server);
wlr_cursor_warp_absolute(server->cursor, &event->pointer->base, event->x, event->y);
wlr_cursor_warp_absolute(server->cursor, &event->pointer->base, event->x,
event->y);
process_cursor_motion(server, event->time_msec);
}
@@ -220,17 +267,20 @@ void cursor_button(struct wl_listener *listener, void *data)
} else {
double sx, sy;
struct wlr_surface *surface = NULL;
absn_toplevel *toplevel = toplevel_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
absn_toplevel *toplevel = toplevel_at(
server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
if (!toplevel)
if (!toplevel) {
goto handle;
}
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(server->seat);
uint32_t mods = wlr_keyboard_get_modifiers(keyboard);
if (mods & CURSOR_MOD) {
if (event->button == CURSOR_MOVE_BUTTON) {
server->cursor_mode = CURSOR_MOVE;
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "all-scroll");
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr,
"all-scroll");
handled = true;
} else if (event->button == CURSOR_RESIZE_BUTTON) {
server->cursor_mode = CURSOR_RESIZE;
@@ -249,24 +299,32 @@ void cursor_button(struct wl_listener *listener, void *data)
server->grab_geom.width = toplevel->geom.width;
server->grab_geom.height = toplevel->geom.height;
if (server->cursor_mode != CURSOR_RESIZE)
if (server->cursor_mode != CURSOR_RESIZE) {
goto handle;
}
int32_t width = toplevel->xdg->base->geometry.width;
int32_t height = toplevel->xdg->base->geometry.height;
if (server->grab_x > (lx + width / 2) && server->grab_y > (ly + height / 2)) {
if (server->grab_x > (lx + width / 2) &&
server->grab_y > (ly + height / 2)) {
server->resize_corner = BOTTOM_RIGHT;
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "se-resize");
} else if (server->grab_x < (lx + width / 2) && server->grab_y > (ly + height / 2)) {
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr,
"se-resize");
} else if (server->grab_x < (lx + width / 2) &&
server->grab_y > (ly + height / 2)) {
server->resize_corner = BOTTOM_LEFT;
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "sw-resize");
} else if (server->grab_x > (lx + width / 2) && server->grab_y < (ly + height / 2)) {
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr,
"sw-resize");
} else if (server->grab_x > (lx + width / 2) &&
server->grab_y < (ly + height / 2)) {
server->resize_corner = TOP_RIGHT;
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "ne-resize");
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr,
"ne-resize");
} else {
server->resize_corner = TOP_LEFT;
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "nw-resize");
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr,
"nw-resize");
}
wlr_xdg_toplevel_set_resizing(toplevel->xdg, true);
@@ -274,7 +332,8 @@ void cursor_button(struct wl_listener *listener, void *data)
handle:
if (!handled) {
wlr_seat_pointer_notify_button(server->seat, event->time_msec, event->button, event->state);
wlr_seat_pointer_notify_button(server->seat, event->time_msec,
event->button, event->state);
}
}
@@ -282,7 +341,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,
wlr_seat_pointer_notify_axis(
server->seat, event->time_msec, event->orientation, event->delta,
event->delta_discrete, event->source, event->relative_direction);
}
@@ -301,16 +361,19 @@ static void new_keyboard(absn_server *server, struct wlr_input_device *device)
keyboard->wlr = wlr_keyboard;
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS);
struct xkb_keymap *keymap =
xkb_keymap_new_from_names(context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS);
wlr_keyboard_set_keymap(wlr_keyboard, keymap);
xkb_keymap_unref(keymap);
xkb_context_unref(context);
wlr_keyboard_set_repeat_info(wlr_keyboard, 25, 600);
LISTEN(keyboard->modifiers, handle_modifiers, wlr_keyboard->events.modifiers);
LISTEN(keyboard->modifiers, handle_modifiers,
wlr_keyboard->events.modifiers);
LISTEN(keyboard->key, handle_key, wlr_keyboard->events.key);
LISTEN(keyboard->destroy, handle_destroy, wlr_keyboard->base.events.destroy);
LISTEN(keyboard->destroy, handle_destroy,
wlr_keyboard->base.events.destroy);
wlr_seat_set_keyboard(server->seat, wlr_keyboard);
+29 -12
View File
@@ -15,11 +15,15 @@ void toplevel_map(struct wl_listener *listener, void *data)
toplevel->scene_tree = wlr_scene_tree_create(server->layers[LAYER_TILE]);
toplevel->scene_tree->node.data = toplevel;
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, toplevel_is_unmanaged(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) {
wlr_xdg_toplevel_set_tiled(toplevel->xdg, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
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);
}
@@ -28,11 +32,13 @@ void toplevel_map(struct wl_listener *listener, void *data)
#ifdef XWAYLAND
if (toplevel->type == TOPLEVEL_X11) {
toplevel->scene_surface = wlr_scene_subsurface_tree_create(toplevel->scene_tree, toplevel->xw->surface);
toplevel->scene_surface = wlr_scene_subsurface_tree_create(
toplevel->scene_tree, toplevel->xw->surface);
} else
#endif
{
toplevel->scene_surface = wlr_scene_xdg_surface_create(toplevel->scene_tree, toplevel->xdg->base);
toplevel->scene_surface = wlr_scene_xdg_surface_create(
toplevel->scene_tree, toplevel->xdg->base);
}
toplevel->scene_surface->node.data = toplevel;
@@ -40,7 +46,8 @@ void toplevel_map(struct wl_listener *listener, void *data)
toplevel->bw = toplevel_is_unmanaged(toplevel) ? 0 : TOPLEVEL_BW;
for (int i = 0; i < 4; ++i) {
toplevel->border[i] = wlr_scene_rect_create(toplevel->scene_tree, 0, 0, unfocused_bc);
toplevel->border[i] =
wlr_scene_rect_create(toplevel->scene_tree, 0, 0, unfocused_bc);
toplevel->border[i]->node.data = toplevel;
}
@@ -66,6 +73,10 @@ void toplevel_unmap(struct wl_listener *listener, void *data)
toplevel->server->seat->keyboard_state.focused_surface = NULL;
}
if (toplevel == toplevel->server->exclusive_focus) {
toplevel->server->exclusive_focus = NULL;
}
wl_list_remove(&toplevel->link);
wl_list_remove(&toplevel->flink);
@@ -108,29 +119,35 @@ void toplevel_request_move(struct wl_listener *listener, void *data)
{
UNUSED(data);
absn_toplevel *toplevel = wl_container_of(listener, toplevel, request_move);
if (toplevel->xdg->base->initialized)
if (toplevel->xdg->base->initialized) {
wlr_xdg_surface_schedule_configure(toplevel->xdg->base);
}
}
void toplevel_request_resize(struct wl_listener *listener, void *data)
{
UNUSED(data);
absn_toplevel *toplevel = wl_container_of(listener, toplevel, request_resize);
if (toplevel->xdg->base->initialized)
absn_toplevel *toplevel =
wl_container_of(listener, toplevel, request_resize);
if (toplevel->xdg->base->initialized) {
wlr_xdg_surface_schedule_configure(toplevel->xdg->base);
}
}
void toplevel_request_maximize(struct wl_listener *listener, void *data)
{
UNUSED(data);
absn_toplevel *toplevel = wl_container_of(listener, toplevel, request_maximize);
if (toplevel->xdg->base->initialized)
absn_toplevel *toplevel =
wl_container_of(listener, toplevel, request_maximize);
if (toplevel->xdg->base->initialized) {
wlr_xdg_surface_schedule_configure(toplevel->xdg->base);
}
}
void toplevel_request_fullscreen(struct wl_listener *listener, void *data)
{
UNUSED(data);
absn_toplevel *toplevel = wl_container_of(listener, toplevel, request_fullscreen);
absn_toplevel *toplevel =
wl_container_of(listener, toplevel, request_fullscreen);
toplevel_set_fullscreen(toplevel, toplevel->xdg->requested.fullscreen);
}
+50 -26
View File
@@ -12,10 +12,11 @@
* its surface and coordinates inside of it
* to process input event
*/
absn_toplevel *toplevel_at(absn_server *server, double lx, double ly, struct wlr_surface **surface, double *sx,
double *sy)
absn_toplevel *toplevel_at(absn_server *server, double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy)
{
struct wlr_scene_node *node = wlr_scene_node_at(&server->scene->tree.node, lx, ly, sx, sy);
struct wlr_scene_node *node =
wlr_scene_node_at(&server->scene->tree.node, lx, ly, sx, sy);
if (!node) {
return NULL;
}
@@ -54,8 +55,9 @@ absn_toplevel *toplevel_at(absn_server *server, double lx, double ly, struct wlr
bool toplevel_is_unmanaged(absn_toplevel *toplevel)
{
#ifdef XWAYLAND
if (toplevel->type == TOPLEVEL_X11)
if (toplevel->type == TOPLEVEL_X11) {
return toplevel->xw->override_redirect;
}
#endif
return false;
}
@@ -80,21 +82,28 @@ static void toplevel_update_borders_geom(absn_toplevel *toplevel)
{
int32_t bw = toplevel->bw;
if (toplevel->geom.width - 2 * bw < 0 || toplevel->geom.height - 2 * bw < 0)
if (toplevel->geom.width - 2 * bw < 0 ||
toplevel->geom.height - 2 * bw < 0) {
return;
}
wlr_scene_node_set_position(&toplevel->scene_tree->node, toplevel->geom.x, toplevel->geom.y);
wlr_scene_node_set_position(&toplevel->scene_tree->node, toplevel->geom.x,
toplevel->geom.y);
wlr_scene_node_set_position(&toplevel->scene_surface->node, bw, bw);
wlr_scene_rect_set_size(toplevel->border[0], toplevel->geom.width - 2 * bw, bw);
wlr_scene_rect_set_size(toplevel->border[1], toplevel->geom.width - 2 * bw, bw);
wlr_scene_rect_set_size(toplevel->border[0], toplevel->geom.width - 2 * bw,
bw);
wlr_scene_rect_set_size(toplevel->border[1], toplevel->geom.width - 2 * bw,
bw);
wlr_scene_rect_set_size(toplevel->border[2], bw, toplevel->geom.height);
wlr_scene_rect_set_size(toplevel->border[3], bw, toplevel->geom.height);
wlr_scene_node_set_position(&toplevel->border[0]->node, bw, 0);
wlr_scene_node_set_position(&toplevel->border[1]->node, bw, toplevel->geom.height - bw);
wlr_scene_node_set_position(&toplevel->border[1]->node, bw,
toplevel->geom.height - bw);
wlr_scene_node_set_position(&toplevel->border[2]->node, 0, 0);
wlr_scene_node_set_position(&toplevel->border[3]->node, toplevel->geom.width - bw, 0);
wlr_scene_node_set_position(&toplevel->border[3]->node,
toplevel->geom.width - bw, 0);
}
void toplevel_set_pos(absn_toplevel *toplevel, int32_t x, int32_t y)
@@ -107,8 +116,9 @@ 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))
(width == toplevel->geom.width && height == toplevel->geom.height)) {
return;
}
toplevel->geom.width = width;
toplevel->geom.height = height;
@@ -124,13 +134,17 @@ void toplevel_set_size(absn_toplevel *toplevel, int32_t width, int32_t height)
};
if (toplevel->type == TOPLEVEL_XDG) {
if (wl_resource_get_version(toplevel->xdg->resource) >= XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION)
if (wl_resource_get_version(toplevel->xdg->resource) >=
XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION) {
wlr_xdg_toplevel_set_bounds(toplevel->xdg, width, height);
toplevel->resizing = wlr_xdg_toplevel_set_size(toplevel->xdg, width - 2 * bw, height - 2 * bw);
}
toplevel->resizing = wlr_xdg_toplevel_set_size(
toplevel->xdg, width - 2 * bw, height - 2 * bw);
}
#ifdef XWAYLAND
else if (toplevel->type == TOPLEVEL_X11) {
wlr_xwayland_surface_configure(toplevel->xw, toplevel->geom.x, toplevel->geom.y, width - 2 * 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);
@@ -148,23 +162,28 @@ void toplevel_set_geom(absn_toplevel *toplevel, struct wlr_box *geom)
void toplevel_set_floating(absn_toplevel *toplevel, bool floating)
{
if (!toplevel || toplevel->floating == floating)
if (!toplevel || toplevel->floating == floating) {
return;
}
toplevel->floating = floating;
if (floating)
wlr_scene_node_reparent(&toplevel->scene_tree->node, toplevel->server->layers[LAYER_FLOAT]);
else
wlr_scene_node_reparent(&toplevel->scene_tree->node, toplevel->server->layers[LAYER_TILE]);
if (floating) {
wlr_scene_node_reparent(&toplevel->scene_tree->node,
toplevel->server->layers[LAYER_FLOAT]);
} else {
wlr_scene_node_reparent(&toplevel->scene_tree->node,
toplevel->server->layers[LAYER_TILE]);
}
layout_arrange(toplevel->output);
}
void toplevel_set_fullscreen(absn_toplevel *toplevel, bool fullscreen)
{
if (!toplevel || toplevel->fullscreen == fullscreen)
if (!toplevel || toplevel->fullscreen == fullscreen) {
return;
}
absn_output *output = toplevel->server->focused_output;
toplevel->fullscreen = fullscreen;
@@ -175,14 +194,18 @@ void toplevel_set_fullscreen(absn_toplevel *toplevel, bool fullscreen)
toplevel->bw = 0;
toplevel_set_geom(toplevel, &output->geom);
wlr_scene_node_reparent(&toplevel->scene_tree->node, toplevel->server->layers[LAYER_FULLSCREEN]);
wlr_scene_node_reparent(&toplevel->scene_tree->node,
toplevel->server->layers[LAYER_FULLSCREEN]);
} else {
toplevel->bw = toplevel_is_unmanaged(toplevel) ? 0 : TOPLEVEL_BW;
toplevel_set_geom(toplevel, &toplevel->prev_geom);
if (toplevel->floating)
wlr_scene_node_reparent(&toplevel->scene_tree->node, toplevel->server->layers[LAYER_FLOAT]);
else
wlr_scene_node_reparent(&toplevel->scene_tree->node, toplevel->server->layers[LAYER_TILE]);
if (toplevel->floating) {
wlr_scene_node_reparent(&toplevel->scene_tree->node,
toplevel->server->layers[LAYER_FLOAT]);
} else {
wlr_scene_node_reparent(&toplevel->scene_tree->node,
toplevel->server->layers[LAYER_TILE]);
}
}
toplevel_update_borders_geom(toplevel);
@@ -192,8 +215,9 @@ void toplevel_set_fullscreen(absn_toplevel *toplevel, bool fullscreen)
void toplevel_set_border_color(absn_toplevel *toplevel, const float color[4])
{
if (!toplevel)
if (!toplevel) {
return;
}
for (int i = 0; i < 4; ++i) {
wlr_scene_rect_set_color(toplevel->border[i], color);
}
+6 -3
View File
@@ -5,9 +5,12 @@
void deco_request_mode(struct wl_listener *listener, void *data)
{
UNUSED(data);
absn_toplevel *toplevel = wl_container_of(listener, toplevel, deco_request_mode);
if (toplevel->xdg->base->initialized)
wlr_xdg_toplevel_decoration_v1_set_mode(toplevel->deco, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
absn_toplevel *toplevel =
wl_container_of(listener, toplevel, deco_request_mode);
if (toplevel->xdg->base->initialized) {
wlr_xdg_toplevel_decoration_v1_set_mode(
toplevel->deco, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
}
}
void deco_destroy(struct wl_listener *listener, void *data)
+12 -11
View File
@@ -1,24 +1,25 @@
#include <stdlib.h>
#include <wayland-server-core.h>
#include "types.h"
void xdg_popup_commit(struct wl_listener *listener, void *data)
{
UNUSED(data);
absn_popup *popup = wl_container_of(listener, popup, commit);
struct wlr_box box;
if (popup->wlr->base->initial_commit)
wlr_xdg_surface_schedule_configure(popup->wlr->base);
if (popup->parent_type == TOPLEVEL_XDG) {
absn_toplevel *toplevel = popup->parent;
box = toplevel->output->usable_area;
box.x -= toplevel->geom.x;
box.y -= toplevel->geom.y;
} else {
absn_layer_surface *layer_surface = popup->parent;
box = layer_surface->output->geom;
box.x -= layer_surface->popups->node.x;
box.y -= layer_surface->popups->node.y;
}
void xdg_popup_destroy(struct wl_listener *listener, void *data)
{
UNUSED(data);
absn_popup *popup = wl_container_of(listener, popup, destroy);
wlr_xdg_popup_unconstrain_from_box(popup->wlr, &box);
wl_list_remove(&popup->commit.link);
wl_list_remove(&popup->destroy.link);
free(popup);
}
+4 -2
View File
@@ -10,15 +10,17 @@ void toplevel_commit(struct wl_listener *listener, void *data)
UNUSED(data);
absn_toplevel *toplevel = wl_container_of(listener, toplevel, commit);
if (toplevel->xdg->base->current.configure_serial < toplevel->resizing)
if (toplevel->xdg->base->current.configure_serial < toplevel->resizing) {
return;
}
if (toplevel->xdg->base->initial_commit) {
wlr_xdg_toplevel_set_activated(toplevel->xdg, false);
/* forse server side decoration mode */
if (toplevel->deco)
if (toplevel->deco) {
deco_request_mode(&toplevel->deco_request_mode, toplevel->deco);
}
/* let client set initial size */
toplevel->resizing = wlr_xdg_toplevel_set_size(toplevel->xdg, 0, 0);
return;
+12 -6
View File
@@ -10,9 +10,10 @@ void xwayland_activate(struct wl_listener *listener, void *data)
UNUSED(data);
absn_toplevel *toplevel = wl_container_of(listener, toplevel, xw_activate);
if (!toplevel_is_unmanaged(toplevel))
if (!toplevel_is_unmanaged(toplevel)) {
wlr_xwayland_surface_activate(toplevel->xw, 1);
}
}
void xwayland_associate(struct wl_listener *listener, void *data)
{
@@ -20,13 +21,15 @@ void xwayland_associate(struct wl_listener *listener, void *data)
absn_toplevel *toplevel = wl_container_of(listener, toplevel, xw_associate);
LISTEN(toplevel->map, toplevel_map, toplevel->xw->surface->events.map);
LISTEN(toplevel->unmap, toplevel_unmap, toplevel->xw->surface->events.unmap);
LISTEN(toplevel->unmap, toplevel_unmap,
toplevel->xw->surface->events.unmap);
}
void xwayland_dissociate(struct wl_listener *listener, void *data)
{
UNUSED(data);
absn_toplevel *toplevel = wl_container_of(listener, toplevel, xw_dissociate);
absn_toplevel *toplevel =
wl_container_of(listener, toplevel, xw_dissociate);
wl_list_remove(&toplevel->map.link);
wl_list_remove(&toplevel->unmap.link);
@@ -39,13 +42,16 @@ void xwayland_configure(struct wl_listener *listener, void *data)
struct wlr_xwayland_surface_configure_event *event = data;
if (!toplevel->xw->surface || !toplevel->xw->surface->mapped) {
wlr_xwayland_surface_configure(toplevel->xw, event->x, event->y, event->width, event->height);
wlr_xwayland_surface_configure(toplevel->xw, event->x, event->y,
event->width, event->height);
return;
}
if (toplevel_is_unmanaged(toplevel)) {
wlr_scene_node_set_position(&toplevel->scene_tree->node, event->x, event->y);
wlr_xwayland_surface_configure(toplevel->xw, event->x, event->y, event->width, event->height);
wlr_scene_node_set_position(&toplevel->scene_tree->node, event->x,
event->y);
wlr_xwayland_surface_configure(toplevel->xw, event->x, event->y,
event->width, event->height);
return;
}
}