diff options
Diffstat (limited to 'rootston')
-rw-r--r-- | rootston/desktop.c | 69 | ||||
-rw-r--r-- | rootston/output.c | 7 | ||||
-rw-r--r-- | rootston/wl_shell.c | 20 | ||||
-rw-r--r-- | rootston/xdg_shell_v6.c | 29 |
4 files changed, 118 insertions, 7 deletions
diff --git a/rootston/desktop.c b/rootston/desktop.c index cf5a8cdc..be74b619 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -89,6 +89,19 @@ void view_move_resize(struct roots_view *view, double x, double y, view_resize(view, width, height); } +static struct wlr_output *view_get_output(struct roots_view *view) { + struct wlr_box view_box; + view_get_box(view, &view_box); + + double output_x, output_y; + wlr_output_layout_closest_point(view->desktop->layout, NULL, + view->x + (double)view_box.width/2, + view->y + (double)view_box.height/2, + &output_x, &output_y); + return wlr_output_layout_output_at(view->desktop->layout, output_x, + output_y); +} + void view_maximize(struct roots_view *view, bool maximized) { if (view->maximized == maximized) { return; @@ -109,13 +122,7 @@ void view_maximize(struct roots_view *view, bool maximized) { view->saved.width = view_box.width; view->saved.height = view_box.height; - double output_x, output_y; - wlr_output_layout_closest_point(view->desktop->layout, NULL, - view->x + (double)view_box.width/2, - view->y + (double)view_box.height/2, - &output_x, &output_y); - struct wlr_output *output = wlr_output_layout_output_at( - view->desktop->layout, output_x, output_y); + struct wlr_output *output = view_get_output(view); struct wlr_box *output_box = wlr_output_layout_get_box(view->desktop->layout, output); @@ -133,6 +140,54 @@ void view_maximize(struct roots_view *view, bool maximized) { } } +void view_set_fullscreen(struct roots_view *view, bool fullscreen, + struct wlr_output *output) { + bool was_fullscreen = view->fullscreen_output != NULL; + if (was_fullscreen == fullscreen) { + // TODO: support changing the output? + return; + } + + // TODO: check if client is focused? + + if (view->set_fullscreen) { + view->set_fullscreen(view, fullscreen); + } + + if (!was_fullscreen && fullscreen) { + if (output == NULL) { + output = view_get_output(view); + } + + struct wlr_box view_box; + view_get_box(view, &view_box); + + view->saved.x = view->x; + view->saved.y = view->y; + view->saved.rotation = view->rotation; + view->saved.width = view_box.width; + view->saved.height = view_box.height; + + struct wlr_box *output_box = + wlr_output_layout_get_box(view->desktop->layout, output); + view_move_resize(view, output_box->x, output_box->y, output_box->width, + output_box->height); + view->rotation = 0; + + wlr_output_set_fullscreen_surface(output, view->wlr_surface); + view->fullscreen_output = output; + } + + if (was_fullscreen && !fullscreen) { + view_move_resize(view, view->saved.x, view->saved.y, view->saved.width, + view->saved.height); + view->rotation = view->saved.rotation; + + wlr_output_set_fullscreen_surface(view->fullscreen_output, NULL); + view->fullscreen_output = NULL; + } +} + void view_close(struct roots_view *view) { if (view->close) { view->close(view); diff --git a/rootston/output.c b/rootston/output.c index 83ff37fd..35a5dac3 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -186,6 +186,13 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { wlr_output_make_current(wlr_output); wlr_renderer_begin(server->renderer, wlr_output); + if (wlr_output->fullscreen_surface != NULL) { + wlr_renderer_end(server->renderer); + wlr_output_swap_buffers(wlr_output); + output->last_frame = desktop->last_frame = now; + return; + } + struct roots_view *view; wl_list_for_each_reverse(view, &desktop->views, link) { render_view(view, desktop, wlr_output, &now); diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 7359c878..f285d7f6 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -59,6 +59,17 @@ static void handle_request_set_maximized(struct wl_listener *listener, view_maximize(view, true); } +static void handle_request_set_fullscreen(struct wl_listener *listener, + void *data) { + struct roots_wl_shell_surface *roots_surface = + wl_container_of(listener, roots_surface, request_set_fullscreen); + struct roots_view *view = roots_surface->view; + struct wlr_wl_shell_surface_set_fullscreen_event *e = data; + + // TODO: support e->method, e->framerate + view_set_fullscreen(view, true, e->output); +} + static void handle_set_state(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, set_state); @@ -68,6 +79,10 @@ static void handle_set_state(struct wl_listener *listener, void *data) { surface->state != WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED) { view_maximize(view, false); } + if (view->fullscreen_output != NULL && + surface->state != WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN) { + view_set_fullscreen(view, false, NULL); + } } static void handle_surface_commit(struct wl_listener *listener, void *data) { @@ -81,6 +96,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&roots_surface->request_move.link); wl_list_remove(&roots_surface->request_resize.link); wl_list_remove(&roots_surface->request_set_maximized.link); + wl_list_remove(&roots_surface->request_set_fullscreen.link); wl_list_remove(&roots_surface->set_state.link); wl_list_remove(&roots_surface->surface_commit.link); view_destroy(roots_surface->view); @@ -111,6 +127,10 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { roots_surface->request_set_maximized.notify = handle_request_set_maximized; wl_signal_add(&surface->events.request_set_maximized, &roots_surface->request_set_maximized); + roots_surface->request_set_fullscreen.notify = + handle_request_set_fullscreen; + wl_signal_add(&surface->events.request_set_fullscreen, + &roots_surface->request_set_fullscreen); roots_surface->set_state.notify = handle_set_state; wl_signal_add(&surface->events.set_state, &roots_surface->set_state); roots_surface->surface_commit.notify = handle_surface_commit; diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 656231c7..9017f7bd 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -100,6 +100,16 @@ static void maximize(struct roots_view *view, bool maximized) { wlr_xdg_toplevel_v6_set_maximized(surface, maximized); } +static void set_fullscreen(struct roots_view *view, bool fullscreen) { + assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); + struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + if (surface->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + return; + } + + wlr_xdg_toplevel_v6_set_fullscreen(surface, fullscreen); +} + static void close(struct roots_view *view) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; @@ -150,6 +160,21 @@ static void handle_request_maximize(struct wl_listener *listener, void *data) { view_maximize(view, surface->toplevel_state->next.maximized); } +static void handle_request_fullscreen(struct wl_listener *listener, + void *data) { + struct roots_xdg_surface_v6 *roots_xdg_surface = + wl_container_of(listener, roots_xdg_surface, request_fullscreen); + struct roots_view *view = roots_xdg_surface->view; + struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + struct wlr_xdg_toplevel_v6_set_fullscreen_event *e = data; + + if (surface->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + return; + } + + view_set_fullscreen(view, e->fullscreen, e->output); +} + static void handle_commit(struct wl_listener *listener, void *data) { //struct roots_xdg_surface_v6 *roots_xdg_surface = // wl_container_of(listener, roots_xdg_surface, commit); @@ -202,6 +227,9 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { roots_surface->request_maximize.notify = handle_request_maximize; wl_signal_add(&surface->events.request_maximize, &roots_surface->request_maximize); + roots_surface->request_fullscreen.notify = handle_request_fullscreen; + wl_signal_add(&surface->events.request_fullscreen, + &roots_surface->request_fullscreen); struct roots_view *view = calloc(1, sizeof(struct roots_view)); if (!view) { @@ -217,6 +245,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { view->resize = resize; view->move_resize = move_resize; view->maximize = maximize; + view->set_fullscreen = set_fullscreen; view->close = close; roots_surface->view = view; view_init(view, desktop); |