feat: add wlr_foreign_toplevel support

This commit is contained in:
DanyLE
2024-04-12 21:18:42 +02:00
parent bca498f387
commit dced6db8b2
9 changed files with 223 additions and 49 deletions

93
view.c
View File

@ -5,6 +5,25 @@
#include "node.h"
#include "seat.h"
#include "output.h"
#include "cursor.h"
static void diyac_view_set_activated(struct diyac_view * view, bool activated)
{
struct diyac_server *server = view->server;
wlr_xdg_toplevel_set_activated(view->xdg_toplevel, activated);
if(view->toplevel.handle)
{
wlr_foreign_toplevel_handle_v1_set_activated(view->toplevel.handle, activated);
}
server->active_view = NULL;
if(activated)
{
diyac_seat_focus_surface(&server->seat, view->xdg_toplevel->base->surface);
server->active_view = view;
}
}
static void raise_to_front(struct diyac_view *view)
{
/* Move the toplevel to the front */
@ -12,8 +31,8 @@ static void raise_to_front(struct diyac_view *view)
wl_list_remove(&view->link);
wl_list_insert(&view->server->views, &view->link);
/* Activate the new surface */
wlr_xdg_toplevel_set_activated(view->xdg_toplevel, true);
}
void diyac_focus_view(struct diyac_view *toplevel, bool raise)
{
/* Note: this function only deals with keyboard focus. */
@ -26,27 +45,15 @@ void diyac_focus_view(struct diyac_view *toplevel, bool raise)
// dont focus unmapped view
return;
}
struct diyac_server *server = toplevel->server;
struct wlr_surface *prev_surface = server->seat.wlr_seat->keyboard_state.focused_surface;
if (prev_surface == toplevel->xdg_toplevel->base->surface)
if(toplevel == toplevel->server->active_view)
{
// Don't re-focus an already focused surface.
wlr_log(WLR_DEBUG, "Don't re-focus an already focused surface");
return;
}
if (prev_surface)
if(toplevel->server->active_view)
{
/*
* Deactivate the previously focused surface. This lets the client know
* it no longer has focus and the client will repaint accordingly, e.g.
* stop displaying a caret.
*/
struct wlr_xdg_toplevel *prev_toplevel =
wlr_xdg_toplevel_try_from_wlr_surface(prev_surface);
if (prev_toplevel != NULL)
{
wlr_xdg_toplevel_set_activated(prev_toplevel, false);
}
diyac_view_set_activated(toplevel->server->active_view, false);
}
raise_to_front(toplevel);
if (raise)
@ -61,13 +68,12 @@ void diyac_focus_view(struct diyac_view *toplevel, bool raise)
}
wl_array_release(&subviews);
}
/*
* Tell the seat to have the keyboard enter this surface. wlroots will keep
* track of this and automatically send key events to the appropriate
* clients without additional work on your part.
*/
diyac_seat_focus_surface(&server->seat, toplevel->xdg_toplevel->base->surface);
diyac_view_set_activated(toplevel, true);
//diyac_seat_focus_surface(&server->seat, toplevel->xdg_toplevel->base->surface);
/*if(toplevel->toplevel.handle)
{
wlr_foreign_toplevel_handle_v1_set_activated(toplevel->toplevel.handle, true);
}*/
}
struct diyac_view *diyac_view_at(
@ -100,6 +106,7 @@ void diyac_focus_topmost_view(struct diyac_server *server, bool raise)
}
else
{
wlr_log(WLR_INFO, "No view found");
/*
* Defocus previous focused surface/view if no longer
* focusable (e.g. unmapped or on a different workspace).
@ -124,7 +131,6 @@ struct diyac_view *diyac_topmost_focusable_view(struct diyac_server *server)
continue;
}
view = diyac_view_from_node(node);
return view;
if (view->mapped /*&& view_is_focusable_from(view, prev)*/)
{
@ -181,12 +187,20 @@ bool diyac_view_update_geometry(struct diyac_view *view, bool grabbed)
if(view->state.fullscreen && !view->requested.fullscreen)
{
wlr_xdg_toplevel_set_fullscreen(view->xdg_toplevel, false);
if(view->toplevel.handle)
{
wlr_foreign_toplevel_handle_v1_set_fullscreen(view->toplevel.handle, false);
}
wlr_scene_node_set_enabled(&view->output->scenes.top->node, true);
view->state.fullscreen = false;
}
if(view->state.maximized && !view->requested.maximized)
{
wlr_xdg_toplevel_set_maximized(view->xdg_toplevel, false);
if(view->toplevel.handle)
{
wlr_foreign_toplevel_handle_v1_set_maximized(view->toplevel.handle, false);
}
view->state.maximized = false;
}
view->state = view->requested;
@ -202,6 +216,10 @@ bool diyac_view_update_geometry(struct diyac_view *view, bool grabbed)
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);
wlr_xdg_toplevel_set_fullscreen(view->xdg_toplevel, false);
if(view->toplevel.handle)
{
wlr_foreign_toplevel_handle_v1_set_fullscreen(view->toplevel.handle, true);
}
return true;
}
else if(view->requested.maximized)
@ -209,6 +227,10 @@ bool diyac_view_update_geometry(struct diyac_view *view, bool grabbed)
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);
if(view->toplevel.handle)
{
wlr_foreign_toplevel_handle_v1_set_maximized(view->toplevel.handle, true);
}
return true;
}
else
@ -304,4 +326,27 @@ struct wlr_box diyac_view_get_geometry(struct diyac_view *view)
return view->output->usable_area;
}
return view->original;
}
void diyac_view_set_maximize(struct diyac_view * view, bool activated)
{
view->requested.maximized = activated;
diyac_reset_cursor_mode(view->server);
diyac_view_update_geometry(view, false);
}
void diyac_view_set_fullscreen(struct diyac_view * view, bool activated)
{
view->requested.fullscreen = activated;
/**
* TODO: use client specific output for fullscreen
* toplevel->xdg_toplevel->requested.fullscreen_output
*/
diyac_reset_cursor_mode(view->server);
diyac_view_update_geometry(view, false);
}
void diyac_view_set_mimimize(struct diyac_view * view, bool activated)
{
// view->requested.minimized = activated;
//TODO implement minimize
wlr_xdg_surface_schedule_configure(view->xdg_toplevel->base);
}