From 1ae9cd000a4e73eca316af10cc128f740eccf282 Mon Sep 17 00:00:00 2001 From: DanyLE Date: Tue, 2 Apr 2024 23:00:11 +0200 Subject: [PATCH] feat: allows fullscreen support --- cursor.c | 15 +++++++----- diyac.h | 2 +- view.c | 74 +++++++++++++++++++++++++++++--------------------------- xdg.c | 67 ++++++++++++-------------------------------------- 4 files changed, 65 insertions(+), 93 deletions(-) diff --git a/cursor.c b/cursor.c index 0ed68e9..ae553be 100644 --- a/cursor.c +++ b/cursor.c @@ -52,17 +52,20 @@ void diyac_reset_cursor_mode(struct diyac_server *server) static void process_cursor_move(struct diyac_server *server, uint32_t time) { - /* Move the grabbed toplevel to the new position. */ struct diyac_view *toplevel = server->grabbed_view; - if (toplevel->state != DIYAC_VIEW_NORMAL) + /* Move the grabbed toplevel to the new position. */ + if (toplevel->state == DIYAC_VIEW_FULL_SCREEN) { - // cancel maximize or fullscreen state + return; + } + if (toplevel->state == DIYAC_VIEW_MAXIMIZE) + { + // cancel maximize state wlr_xdg_toplevel_set_maximized(toplevel->xdg_toplevel, false); - wlr_xdg_toplevel_set_fullscreen(toplevel->xdg_toplevel, false); // move the windows to cursor server->grab_x = toplevel->original.width * server->grab_x / toplevel->output->usable_area.width; } - toplevel->state = DIYAC_VIEW_NORMAL; + toplevel->requested = DIYAC_VIEW_NORMAL; toplevel->original.y = server->seat.cursor->y - server->grab_y; toplevel->original.x = server->seat.cursor->x - server->grab_x; @@ -135,7 +138,7 @@ static void process_cursor_resize(struct diyac_server *server, uint32_t time) int new_height = new_bottom - new_top; toplevel->original.width = new_width; toplevel->original.height = new_height; - toplevel->state = DIYAC_VIEW_NORMAL; + toplevel->requested = DIYAC_VIEW_NORMAL; diyac_view_update_geometry(toplevel, false); /* wlr_scene_node_set_position(&toplevel->scene_tree->node, diff --git a/diyac.h b/diyac.h index 23031a2..7097d1c 100644 --- a/diyac.h +++ b/diyac.h @@ -41,7 +41,6 @@ enum diyac_view_state { DIYAC_VIEW_NORMAL = 0, DIYAC_VIEW_MAXIMIZE, - DIYAC_VIEW_MINIMIZE, DIYAC_VIEW_FULL_SCREEN, }; @@ -167,6 +166,7 @@ struct diyac_view struct wlr_xdg_toplevel *xdg_toplevel; struct wlr_scene_tree *scene_tree; enum diyac_view_state state; + enum diyac_view_state requested; /* * Geometry of the wlr_surface contained within the view, as * currently displayed. Should be kept in sync with the diff --git a/view.c b/view.c index 6f368dd..f4d8e45 100644 --- a/view.c +++ b/view.c @@ -155,91 +155,95 @@ void diyac_arrange_all_views(struct diyac_server *server) bool diyac_view_update_geometry(struct diyac_view *view, bool grabbed) { assert(view); - bool adjusted = false; - struct wlr_box geo_box; + struct wlr_box geo_box, intersect_box; struct wlr_box *geometry = &view->original; // if (wlr_output_layout_intersects(view->server->output_layout, // view->output->wlr_output, &view->current)) //{ + if (!view->mapped) + { + wlr_xdg_surface_schedule_configure(view->xdg_toplevel->base); + return false; + } struct wlr_box usable = diyac_output_usable_area(view->output); wlr_log(WLR_DEBUG, "diyac_view_update_geometry: current: [%d,%d,%d,%d], usable: [%d,%d,%d,%d] ", geometry->x, geometry->y, geometry->width, geometry->height, usable.x, usable.y, usable.width, usable.height); struct diyac_server *server = view->server; - if (!view->mapped) + wlr_box_intersection(&intersect_box,geometry, &usable); + wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box); + if ( wlr_box_equal(geometry, &geo_box) && (view->state == view->requested) && wlr_box_empty(&intersect_box)) { - view->state = DIYAC_VIEW_NORMAL; + wlr_log(WLR_INFO, "No geometry update needed"); return false; } - switch (view->state) + // invalidate old state if change state + if(view->requested != view->state) + { + switch (view->state) + { + case DIYAC_VIEW_MAXIMIZE: + wlr_xdg_toplevel_set_maximized(view->xdg_toplevel, false); + break; + case DIYAC_VIEW_FULL_SCREEN: + wlr_xdg_toplevel_set_fullscreen(view->xdg_toplevel, false); + wlr_scene_node_set_enabled(&view->output->scenes.top->node, true); + break; + default: + break; + } + } + switch (view->requested) { case DIYAC_VIEW_MAXIMIZE: - /** - * We dont change the current_view geometry in maximize state - * - */ wlr_scene_node_set_position(&view->scene_tree->node, usable.x, usable.y); wlr_xdg_toplevel_set_size(view->xdg_toplevel, usable.width, usable.height); + wlr_xdg_toplevel_set_maximized(view->xdg_toplevel, true); + view->state = DIYAC_VIEW_MAXIMIZE; return true; - case DIYAC_VIEW_MINIMIZE: - view->state = DIYAC_VIEW_NORMAL; - wlr_log(WLR_INFO, "diyac_view_update_geometry: minimize ignore"); - return false; case DIYAC_VIEW_FULL_SCREEN: - /*TODO: implement full-screen */ - //view->state = DIYAC_VIEW_NORMAL; - wlr_log(WLR_INFO, "diyac_view_update_geometry: full-screen ignore"); + wlr_scene_node_set_enabled(&view->output->scenes.top->node, false); + wlr_scene_node_set_position(&view->scene_tree->node, 0, 0); + wlr_xdg_toplevel_set_size(view->xdg_toplevel, view->output->wlr_output->width, view->output->wlr_output->height); + view->state = DIYAC_VIEW_FULL_SCREEN; + wlr_xdg_toplevel_set_fullscreen(view->xdg_toplevel, false); return false; default: - wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box); - if (!wlr_box_equal(geometry, &geo_box)) - { - adjusted = true; - } // if (wlr_output_layout_intersects(view->server->output_layout, // view->output->wlr_output, &view->current)) //{ /**Normal state, recalculate current geometry*/ - + view->state = DIYAC_VIEW_NORMAL; if (!grabbed && geometry->x < usable.x) { geometry->x = usable.x; - adjusted = true; } if (!grabbed && geometry->y < usable.y) { geometry->y = usable.y; - adjusted = true; } if (grabbed && server->seat.cursor->x <= usable.x) { geometry->x = usable.x - server->grab_x; - adjusted = true; } if (grabbed && server->seat.cursor->y <= usable.y) { geometry->y = usable.y; - adjusted = true; } if (grabbed && server->seat.cursor->x >= usable.x + usable.width) { geometry->x = usable.x + usable.width - server->grab_x; - adjusted = true; } if (grabbed && server->seat.cursor->y >= usable.y + usable.height) { geometry->y = usable.y + usable.height - server->grab_y; - adjusted = true; } - if (adjusted) - { - wlr_log(WLR_DEBUG, "diyac_view_update_geometry: updating geometry: %d %d %d %d", geometry->x, geometry->y, geometry->width, geometry->height); - wlr_scene_node_set_position(&view->scene_tree->node, geometry->x, geometry->y); - wlr_xdg_toplevel_set_size(view->xdg_toplevel, geometry->width, geometry->height); - } - return adjusted; + wlr_log(WLR_DEBUG, "diyac_view_update_geometry: updating geometry: %d %d %d %d", geometry->x, geometry->y, geometry->width, geometry->height); + wlr_scene_node_set_position(&view->scene_tree->node, geometry->x, geometry->y); + wlr_xdg_toplevel_set_size(view->xdg_toplevel, geometry->width, geometry->height); + return true; } } diff --git a/xdg.c b/xdg.c index 24f3c4b..e582386 100644 --- a/xdg.c +++ b/xdg.c @@ -79,10 +79,7 @@ static void xdg_toplevel_map(struct wl_listener *listener, void *data) toplevel->original.height = toplevel->output->usable_area.height; } diyac_view_update_geometry(toplevel, false); - if (toplevel->state != DIYAC_VIEW_MINIMIZE) - { - diyac_focus_view(toplevel, false); - } + diyac_focus_view(toplevel, false); } static void xdg_toplevel_unmap(struct wl_listener *listener, void *data) @@ -136,74 +133,41 @@ static void xdg_toplevel_request_maximize( struct diyac_view *toplevel = wl_container_of(listener, toplevel, request_maximize); - if (!toplevel->mapped) + if(toplevel->xdg_toplevel->requested.maximized) { - wlr_xdg_toplevel_set_maximized(toplevel->xdg_toplevel, false); - // the view has not yet be mapped, don't maximize it - wlr_log(WLR_INFO, "The view has not yet be mapped, ignore maximize request"); - return; + toplevel->requested = DIYAC_VIEW_MAXIMIZE; + } + else if(toplevel->state == DIYAC_VIEW_MAXIMIZE) + { + toplevel->requested = DIYAC_VIEW_NORMAL; } wlr_log(WLR_INFO, "Request maximize"); diyac_reset_cursor_mode(toplevel->server); - if (toplevel->state == DIYAC_VIEW_MAXIMIZE) - { - toplevel->state = DIYAC_VIEW_NORMAL; - wlr_xdg_toplevel_set_maximized(toplevel->xdg_toplevel, false); - // restore its default geometry - } - else - { - wlr_xdg_toplevel_set_maximized(toplevel->xdg_toplevel, true); - toplevel->state = DIYAC_VIEW_MAXIMIZE; - } diyac_view_update_geometry(toplevel, false); - // wlr_xdg_surface_schedule_configure(toplevel->xdg_toplevel->base); } static void xdg_toplevel_request_fullscreen(struct wl_listener *listener, void *data) { struct diyac_view *toplevel = wl_container_of(listener, toplevel, request_fullscreen); - if (!toplevel->mapped) + if(toplevel->xdg_toplevel->requested.fullscreen) { - wlr_xdg_toplevel_set_fullscreen(toplevel->xdg_toplevel, false); - // the view has not yet be mapped, don't maximize it - wlr_log(WLR_INFO, "The view has not yet be mapped, ignore fullscreen request"); - return; + toplevel->requested = DIYAC_VIEW_FULL_SCREEN; + } + else if(toplevel->state == DIYAC_VIEW_FULL_SCREEN) + { + toplevel->requested = DIYAC_VIEW_NORMAL; } wlr_log(WLR_INFO, "Request fullscreen"); diyac_reset_cursor_mode(toplevel->server); - wlr_xdg_toplevel_set_fullscreen(toplevel->xdg_toplevel, false); - /* - if (toplevel->state == DIYAC_VIEW_FULL_SCREEN) - { - toplevel->state = DIYAC_VIEW_NORMAL; - wlr_xdg_toplevel_set_fullscreen(toplevel->xdg_toplevel, false); - // restore its default geometry - } - else - { - toplevel->state = DIYAC_VIEW_FULL_SCREEN; - } - - */ - // diyac_view_update_geometry(toplevel, false); + diyac_view_update_geometry(toplevel, false); } static void xdg_toplevel_request_minimize(struct wl_listener *listener, void *data) { struct diyac_view *toplevel = wl_container_of(listener, toplevel, request_minimize); - if (toplevel->state == DIYAC_VIEW_MINIMIZE) - { - toplevel->state = DIYAC_VIEW_NORMAL; - // restore its default geometry - } - else - { - toplevel->state = DIYAC_VIEW_MINIMIZE; - } - diyac_view_update_geometry(toplevel, false); + wlr_xdg_surface_schedule_configure(toplevel->xdg_toplevel->base); } static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) @@ -387,6 +351,7 @@ void diyac_new_xdg_surface(struct wl_listener *listener, void *data) /* Allocate a diyac_view for this surface */ struct diyac_view *toplevel = calloc(1, sizeof(*toplevel)); toplevel->state = DIYAC_VIEW_NORMAL; + toplevel->requested = DIYAC_VIEW_NORMAL; toplevel->server = server; toplevel->xdg_toplevel = xdg_surface->toplevel; toplevel->xdg_surface = xdg_surface;