diff --git a/include/absinthe-toplevel.h b/include/absinthe-toplevel.h index edb8810..8ef28c2 100644 --- a/include/absinthe-toplevel.h +++ b/include/absinthe-toplevel.h @@ -4,5 +4,7 @@ struct absinthe_toplevel *absinthe_toplevel_at(struct absinthe_server *server, d void absinthe_toplevel_set_position(struct absinthe_toplevel *toplevel, int32_t x, int32_t y); void absinthe_toplevel_set_size(struct absinthe_toplevel *toplevel, int32_t width, int32_t height); +void absinthe_toplevel_set_fullscreen(struct absinthe_toplevel *toplevel, bool fullscreen); + void absinthe_toplevel_set_border_color(struct absinthe_toplevel *toplevel, const float color[4]); void absinthe_toplevel_update_borders_geometry(struct absinthe_toplevel *toplevel); diff --git a/include/types.h b/include/types.h index 941a0be..74ffb5b 100644 --- a/include/types.h +++ b/include/types.h @@ -26,9 +26,6 @@ static const float bordercolor[4] = {0.88, 0.18, 0.18, 1.0}; -#define MAX(a, b) a > b ? a : b -#define MIN(a, b) a < b ? a : b - enum absinthe_cursor_mode { ABSINTHE_CURSOR_PASSTHROUGH, ABSINTHE_CURSOR_MOVE, @@ -42,6 +39,8 @@ enum absinthe_cursor_resize_corner { ABSINTHE_CURSOR_RESIZE_CORNER_BOTTOM_RIGHT, }; +struct absinthe_output; + struct absinthe_server { struct wl_display *display; struct wlr_backend *backend; @@ -78,6 +77,7 @@ struct absinthe_server { uint32_t grab_x, grab_y; enum absinthe_cursor_resize_corner cursor_resize_corner; + struct absinthe_output *focused_output; struct wl_list outputs; struct wl_listener new_output; struct wlr_output_layout *output_layout; @@ -100,11 +100,15 @@ struct absinthe_output { struct absinthe_toplevel { struct wl_list link; struct absinthe_server *server; + struct absinthe_output *output; struct wlr_scene_tree *scene_tree; struct wlr_scene_tree *scene_surface; + int32_t border_width; struct wlr_scene_rect *border[4]; + bool fullscreen; bool performing_resize; struct wlr_box geometry; + struct wlr_box prev_geometry; struct wlr_xdg_toplevel *xdg_toplevel; struct wl_listener map; struct wl_listener unmap; diff --git a/src/absinthe-toplevel.c b/src/absinthe-toplevel.c index 09b9c2f..6f1d43d 100644 --- a/src/absinthe-toplevel.c +++ b/src/absinthe-toplevel.c @@ -32,13 +32,33 @@ void absinthe_toplevel_set_position(struct absinthe_toplevel *toplevel, int32_t void absinthe_toplevel_set_size(struct absinthe_toplevel *toplevel, int32_t width, int32_t height) { - int bw = ABSINTHE_WINDOW_BORDER_WIDTH; + int32_t bw = toplevel->border_width; if (width < 0 || height < 0) return; wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, width, height); - wlr_xdg_surface_schedule_configure(toplevel->xdg_toplevel->base); +} + +void absinthe_toplevel_set_fullscreen(struct absinthe_toplevel *toplevel, bool fullscreen) +{ + if (!toplevel || toplevel->fullscreen == fullscreen) + return; + + struct absinthe_output *output = toplevel->output; + toplevel->fullscreen = fullscreen; + wlr_xdg_toplevel_set_fullscreen(toplevel->xdg_toplevel, fullscreen); + + if (fullscreen) { + toplevel->prev_geometry = toplevel->geometry; + toplevel->geometry = output->geometry; + toplevel->border_width = 0; + absinthe_toplevel_set_size(toplevel, toplevel->geometry.width, toplevel->geometry.height); + } else { + toplevel->geometry = toplevel->prev_geometry; + toplevel->border_width = ABSINTHE_WINDOW_BORDER_WIDTH; + absinthe_toplevel_set_size(toplevel, toplevel->geometry.width, toplevel->geometry.height); + } } void absinthe_toplevel_set_border_color(struct absinthe_toplevel *toplevel, const float color[4]) @@ -50,11 +70,12 @@ void absinthe_toplevel_set_border_color(struct absinthe_toplevel *toplevel, cons void absinthe_toplevel_update_borders_geometry(struct absinthe_toplevel *toplevel) { - int bw = ABSINTHE_WINDOW_BORDER_WIDTH; + int32_t bw = toplevel->border_width; if (toplevel->geometry.width - 2 * bw < 0 || toplevel->geometry.height - 2 * bw < 0) return; + wlr_scene_node_set_position(&toplevel->scene_tree->node, toplevel->geometry.x, toplevel->geometry.y); wlr_scene_node_set_position(&toplevel->scene_surface->node, bw, bw); diff --git a/src/cursor.c b/src/cursor.c index d8f7899..14c5d45 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -30,7 +30,7 @@ static void process_cursor_move(struct absinthe_server *server) { static void apply_resize(struct absinthe_toplevel *toplevel, struct wlr_box *new_geometry) { - int32_t bw = ABSINTHE_WINDOW_BORDER_WIDTH; + int32_t bw = toplevel->border_width; int32_t min_width = toplevel->xdg_toplevel->current.min_width; int32_t min_height = toplevel->xdg_toplevel->current.min_height; diff --git a/src/keyboard.c b/src/keyboard.c index 66fd0f0..19c4e4f 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -3,8 +3,11 @@ #include #include +#include +#include #include "types.h" +#include "absinthe-toplevel.h" void keyboard_handle_modifiers(struct wl_listener *listener, void *data) { @@ -24,6 +27,22 @@ static bool keyboard_handle_keybind(struct absinthe_server *server, xkb_keysym_t if (fork() == 0) execl("/bin/sh", "sh", "-c", "alacritty", NULL); break; + case XKB_KEY_f: + struct wlr_surface *surface = server->seat->pointer_state.focused_surface; + + if (!surface) + break; + + struct wlr_xdg_toplevel *xdg_toplevel = wlr_xdg_toplevel_try_from_wlr_surface(surface); + + if (!xdg_toplevel) + break; + + struct absinthe_toplevel *toplevel = xdg_toplevel->base->data; + + if (toplevel) + absinthe_toplevel_set_fullscreen(toplevel, !toplevel->fullscreen); + break; default: return false; } diff --git a/src/server.c b/src/server.c index e568604..881e23c 100644 --- a/src/server.c +++ b/src/server.c @@ -25,9 +25,8 @@ void server_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); @@ -49,6 +48,8 @@ void server_new_output(struct wl_listener *listener, void *data) 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, &output->geometry); + + server->focused_output = output; } void server_new_xdg_toplevel(struct wl_listener *listener, void *data) diff --git a/src/xdg-toplevel.c b/src/xdg-toplevel.c index 39afee8..e483875 100644 --- a/src/xdg-toplevel.c +++ b/src/xdg-toplevel.c @@ -12,13 +12,16 @@ 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) { + // Let client set the preferred size wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, 0, 0); + // Forse server side decoration mode if (toplevel->decoration) xdg_decoration_request_mode(&toplevel->decoration_request_mode, toplevel->decoration); } else { + // Check for size because we did't set it on initial commit if (toplevel->geometry.width == 0 || toplevel->geometry.height == 0) { - int bw = ABSINTHE_WINDOW_BORDER_WIDTH; + int32_t bw = toplevel->border_width; toplevel->geometry.width = toplevel->xdg_toplevel->base->geometry.width + 2 * bw; toplevel->geometry.height = toplevel->xdg_toplevel->base->geometry.height + 2 * bw; } @@ -38,9 +41,14 @@ void xdg_toplevel_map(struct wl_listener *listener, void *data) toplevel->border[i]->node.data = toplevel; } + toplevel->border_width = ABSINTHE_WINDOW_BORDER_WIDTH; + absinthe_toplevel_set_border_color(toplevel, bordercolor); absinthe_toplevel_update_borders_geometry(toplevel); + toplevel->output = toplevel->server->focused_output; + toplevel->fullscreen = false; + wl_list_insert(&toplevel->server->toplevels, &toplevel->link); } @@ -93,6 +101,5 @@ void xdg_toplevel_request_maximize(struct wl_listener *listener, void *data) void xdg_toplevel_request_fullscreen(struct wl_listener *listener, void *data) { struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_fullscreen); - if (toplevel->xdg_toplevel->base->initialized) - wlr_xdg_surface_schedule_configure(toplevel->xdg_toplevel->base); + absinthe_toplevel_set_fullscreen(toplevel, toplevel->xdg_toplevel->requested.fullscreen); }