From b04a9a248d4cf3d0e93e1b39ee9eedc9da359173 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 20 Nov 2017 17:27:36 +0100 Subject: Initial fullscreen support --- include/rootston/view.h | 6 ++++++ include/wlr/types/wlr_output.h | 6 ++++++ include/wlr/types/wlr_xdg_shell_v6.h | 7 +++++++ 3 files changed, 19 insertions(+) (limited to 'include') diff --git a/include/rootston/view.h b/include/rootston/view.h index 69034d60..e1397b89 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -13,6 +13,7 @@ struct roots_wl_shell_surface { struct wl_listener request_move; struct wl_listener request_resize; struct wl_listener request_set_maximized; + struct wl_listener request_set_fullscreen; struct wl_listener set_state; struct wl_listener surface_commit; @@ -26,6 +27,7 @@ struct roots_xdg_surface_v6 { struct wl_listener request_move; struct wl_listener request_resize; struct wl_listener request_maximize; + struct wl_listener request_fullscreen; }; struct roots_xwayland_surface { @@ -54,6 +56,7 @@ struct roots_view { float rotation; bool maximized; + struct wlr_output *fullscreen_output; struct { double x, y; uint32_t width, height; @@ -93,6 +96,7 @@ struct roots_view { void (*move_resize)(struct roots_view *view, double x, double y, uint32_t width, uint32_t height); void (*maximize)(struct roots_view *view, bool maximized); + void (*set_fullscreen)(struct roots_view *view, bool fullscreen); void (*close)(struct roots_view *view); }; @@ -103,6 +107,8 @@ void view_resize(struct roots_view *view, uint32_t width, uint32_t height); void view_move_resize(struct roots_view *view, double x, double y, uint32_t width, uint32_t height); void view_maximize(struct roots_view *view, bool maximized); +void view_set_fullscreen(struct roots_view *view, bool fullscreen, + struct wlr_output *output); void view_close(struct roots_view *view); bool view_center(struct roots_view *view); void view_setup(struct roots_view *view); diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index cf000019..d382b593 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -64,6 +64,10 @@ struct wlr_output { struct wl_signal destroy; } events; + struct wlr_surface *fullscreen_surface; + struct wl_listener fullscreen_surface_commit; + struct wl_listener fullscreen_surface_destroy; + struct wl_list cursors; // wlr_output_cursor::link struct wlr_output_cursor *hardware_cursor; @@ -89,6 +93,8 @@ void wlr_output_swap_buffers(struct wlr_output *output); void wlr_output_set_gamma(struct wlr_output *output, uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b); uint32_t wlr_output_get_gamma_size(struct wlr_output *output); +void wlr_output_set_fullscreen_surface(struct wlr_output *output, + struct wlr_surface *surface); struct wlr_output_cursor *wlr_output_cursor_create(struct wlr_output *output); bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index e3982003..7940deef 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -152,6 +152,13 @@ struct wlr_xdg_toplevel_v6_resize_event { uint32_t edges; }; +struct wlr_xdg_toplevel_v6_set_fullscreen_event { + struct wl_client *client; + struct wlr_xdg_surface_v6 *surface; + bool fullscreen; + struct wlr_output *output; +}; + struct wlr_xdg_toplevel_v6_show_window_menu_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; -- cgit v1.2.3 From 80998cdf57756fe46d55921c98a745aff4848215 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 20 Nov 2017 17:58:26 +0100 Subject: Add support for fullscreen xwayland views --- include/rootston/view.h | 1 + rootston/xwayland.c | 21 +++++++++++++++++++++ types/wlr_output.c | 4 ++++ 3 files changed, 26 insertions(+) (limited to 'include') diff --git a/include/rootston/view.h b/include/rootston/view.h index e1397b89..77bbfbec 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -38,6 +38,7 @@ struct roots_xwayland_surface { struct wl_listener request_move; struct wl_listener request_resize; struct wl_listener request_maximize; + struct wl_listener request_fullscreen; struct wl_listener map_notify; struct wl_listener unmap_notify; }; diff --git a/rootston/xwayland.c b/rootston/xwayland.c index c92c424b..5e27afed 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -92,6 +92,13 @@ static void maximize(struct roots_view *view, bool maximized) { view->xwayland_surface, maximized); } +static void set_fullscreen(struct roots_view *view, bool fullscreen) { + assert(view->type == ROOTS_XWAYLAND_VIEW); + + wlr_xwayland_surface_set_fullscreen(view->desktop->xwayland, + view->xwayland_surface, fullscreen); +} + static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, destroy); @@ -170,6 +177,16 @@ static void handle_request_maximize(struct wl_listener *listener, void *data) { view_maximize(view, maximized); } +static void handle_request_fullscreen(struct wl_listener *listener, + void *data) { + struct roots_xwayland_surface *roots_surface = + wl_container_of(listener, roots_surface, request_fullscreen); + struct roots_view *view = roots_surface->view; + struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; + + view_set_fullscreen(view, xwayland_surface->fullscreen, NULL); +} + static void handle_map_notify(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, map_notify); @@ -223,6 +240,9 @@ void handle_xwayland_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 == NULL) { @@ -240,6 +260,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { view->move = move; view->move_resize = move_resize; view->maximize = maximize; + view->set_fullscreen = set_fullscreen; view->close = close; roots_surface->view = view; view_init(view, desktop); diff --git a/types/wlr_output.c b/types/wlr_output.c index 5a8baa3d..3ef91179 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -382,6 +382,10 @@ static void output_fullscreen_surface_handle_destroy( void wlr_output_set_fullscreen_surface(struct wlr_output *output, struct wlr_surface *surface) { // TODO: hardware fullscreen + if (output->fullscreen_surface == surface) { + return; + } + output_fullscreen_surface_reset(output); output->fullscreen_surface = surface; -- cgit v1.2.3 From abab2902f5051bcde93b34b5a57bf9bae93b3bab Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 20 Nov 2017 19:45:10 +0100 Subject: Check for subsurfaces and popups before using wlr_output_set_fullscreen_surface --- include/rootston/desktop.h | 5 +++-- include/rootston/view.h | 2 +- rootston/desktop.c | 16 +++++++++++++--- rootston/output.c | 27 ++++++++++++++++++++++++++- 4 files changed, 43 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index c245eb09..8bf1f6eb 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -19,13 +19,14 @@ struct roots_output { struct wlr_output *wlr_output; struct wl_listener frame; struct timespec last_frame; - struct wl_list link; + struct wl_list link; // roots_desktop:outputs + struct roots_view *fullscreen_view; }; struct roots_desktop { struct wl_list views; // roots_view::link - struct wl_list outputs; + struct wl_list outputs; // roots_output::link struct timespec last_frame; struct roots_server *server; diff --git a/include/rootston/view.h b/include/rootston/view.h index 77bbfbec..44a98115 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -57,7 +57,7 @@ struct roots_view { float rotation; bool maximized; - struct wlr_output *fullscreen_output; + struct roots_output *fullscreen_output; struct { double x, y; uint32_t width, height; diff --git a/rootston/desktop.c b/rootston/desktop.c index be74b619..b48da44b 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -174,8 +174,14 @@ void view_set_fullscreen(struct roots_view *view, bool fullscreen, output_box->height); view->rotation = 0; - wlr_output_set_fullscreen_surface(output, view->wlr_surface); - view->fullscreen_output = output; + struct roots_output *roots_output; + wl_list_for_each(roots_output, &view->desktop->outputs, link) { + if (roots_output->wlr_output == output) { + roots_output->fullscreen_view = view; + view->fullscreen_output = roots_output; + break; + } + } } if (was_fullscreen && !fullscreen) { @@ -183,7 +189,7 @@ void view_set_fullscreen(struct roots_view *view, bool fullscreen, view->saved.height); view->rotation = view->saved.rotation; - wlr_output_set_fullscreen_surface(view->fullscreen_output, NULL); + view->fullscreen_output->fullscreen_view = NULL; view->fullscreen_output = NULL; } } @@ -236,6 +242,10 @@ bool view_center(struct roots_view *view) { void view_destroy(struct roots_view *view) { wl_signal_emit(&view->events.destroy, view); + if (view->fullscreen_output) { + view->fullscreen_output->fullscreen_view = NULL; + } + wl_list_remove(&view->link); free(view); } diff --git a/rootston/output.c b/rootston/output.c index 35a5dac3..82618b06 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -174,6 +174,22 @@ static void render_view(struct roots_view *view, struct roots_desktop *desktop, } } +static bool has_standalone_surface(struct roots_view *view) { + if (!wl_list_empty(&view->wlr_surface->subsurface_list)) { + wlr_log(L_DEBUG, "has subsurfaces"); + return false; + } + + switch (view->type) { + case ROOTS_XDG_SHELL_V6_VIEW: + return wl_list_empty(&view->xdg_surface_v6->popups); + case ROOTS_WL_SHELL_VIEW: + return wl_list_empty(&view->wl_shell_surface->popups); + case ROOTS_XWAYLAND_VIEW: + return true; + } +} + static void output_frame_notify(struct wl_listener *listener, void *data) { struct wlr_output *wlr_output = data; struct roots_output *output = wl_container_of(listener, output, frame); @@ -186,11 +202,20 @@ 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) { + if (output->fullscreen_view != NULL) { + if (has_standalone_surface(output->fullscreen_view)) { + wlr_output_set_fullscreen_surface(wlr_output, + output->fullscreen_view->wlr_surface); + } else { + wlr_output_set_fullscreen_surface(wlr_output, NULL); + render_view(output->fullscreen_view, desktop, wlr_output, &now); + } wlr_renderer_end(server->renderer); wlr_output_swap_buffers(wlr_output); output->last_frame = desktop->last_frame = now; return; + } else { + wlr_output_set_fullscreen_surface(wlr_output, NULL); } struct roots_view *view; -- cgit v1.2.3 From 54f1135c057e76b1c05058592a6878a07a524b99 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 20 Nov 2017 20:53:13 +0100 Subject: Fix fullscreen in xdg-shell --- include/wlr/types/wlr_surface.h | 8 ++++++-- rootston/output.c | 12 +----------- types/wlr_output.c | 39 +++++++++++++++++++-------------------- types/wlr_surface.c | 14 ++++++++++++++ 4 files changed, 40 insertions(+), 33 deletions(-) (limited to 'include') diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index cea53109..c8e3761a 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -1,9 +1,10 @@ #ifndef WLR_TYPES_WLR_SURFACE_H #define WLR_TYPES_WLR_SURFACE_H -#include -#include #include #include +#include +#include +#include #include struct wlr_frame_callback { @@ -142,4 +143,7 @@ void wlr_surface_send_enter(struct wlr_surface *surface, void wlr_surface_send_leave(struct wlr_surface *surface, struct wlr_output *output); +void wlr_surface_send_frame_done(struct wlr_surface *surface, + const struct timespec *when); + #endif diff --git a/rootston/output.c b/rootston/output.c index 82618b06..52db62f1 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -13,10 +13,6 @@ #include "rootston/desktop.h" #include "rootston/config.h" -static inline int64_t timespec_to_msec(const struct timespec *a) { - return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; -} - /** * Rotate a child's position relative to a parent. The parent size is (pw, ph), * the child position is (*sx, *sy) and its size is (sw, sh). @@ -75,12 +71,7 @@ static void render_surface(struct wlr_surface *surface, wlr_render_with_matrix(desktop->server->renderer, surface->texture, &matrix); - struct wlr_frame_callback *cb, *cnext; - wl_list_for_each_safe(cb, cnext, - &surface->current->frame_callback_list, link) { - wl_callback_send_done(cb->resource, timespec_to_msec(when)); - wl_resource_destroy(cb->resource); - } + wlr_surface_send_frame_done(surface, when); } struct wlr_subsurface *subsurface; @@ -176,7 +167,6 @@ static void render_view(struct roots_view *view, struct roots_desktop *desktop, static bool has_standalone_surface(struct roots_view *view) { if (!wl_list_empty(&view->wlr_surface->subsurface_list)) { - wlr_log(L_DEBUG, "has subsurfaces"); return false; } diff --git a/types/wlr_output.c b/types/wlr_output.c index 3ef91179..8accf7a5 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -253,7 +253,7 @@ void wlr_output_make_current(struct wlr_output *output) { } static void output_fullscreen_surface_render(struct wlr_output *output, - struct wlr_surface *surface) { + struct wlr_surface *surface, const struct timespec *when) { int x = (output->width - surface->current->width) / 2; int y = (output->height - surface->current->height) / 2; @@ -268,6 +268,8 @@ static void output_fullscreen_surface_render(struct wlr_output *output, wlr_texture_get_matrix(surface->texture, &matrix, &output->transform_matrix, x, y); wlr_render_with_matrix(surface->renderer, surface->texture, &matrix); + + wlr_surface_send_frame_done(surface, when); } static void output_cursor_get_box(struct wlr_output_cursor *cursor, @@ -278,7 +280,8 @@ static void output_cursor_get_box(struct wlr_output_cursor *cursor, box->height = cursor->height; } -static void output_cursor_render(struct wlr_output_cursor *cursor) { +static void output_cursor_render(struct wlr_output_cursor *cursor, + const struct timespec *when) { struct wlr_texture *texture = cursor->texture; struct wlr_renderer *renderer = cursor->renderer; if (cursor->surface != NULL) { @@ -321,13 +324,21 @@ static void output_cursor_render(struct wlr_output_cursor *cursor) { wlr_texture_get_matrix(texture, &matrix, &cursor->output->transform_matrix, x, y); wlr_render_with_matrix(renderer, texture, &matrix); + + if (cursor->surface != NULL) { + wlr_surface_send_frame_done(cursor->surface, when); + } } void wlr_output_swap_buffers(struct wlr_output *output) { wl_signal_emit(&output->events.swap_buffers, &output); + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + if (output->fullscreen_surface != NULL) { - output_fullscreen_surface_render(output, output->fullscreen_surface); + output_fullscreen_surface_render(output, output->fullscreen_surface, + &now); } struct wlr_output_cursor *cursor; @@ -335,7 +346,7 @@ void wlr_output_swap_buffers(struct wlr_output *output) { if (!cursor->enabled || output->hardware_cursor == cursor) { continue; } - output_cursor_render(cursor); + output_cursor_render(cursor, &now); } output->impl->swap_buffers(output); @@ -472,30 +483,18 @@ static void output_cursor_commit(struct wlr_output_cursor *cursor) { cursor->output->needs_swap = true; } else { // TODO: upload pixels - } -} -static inline int64_t timespec_to_msec(const struct timespec *a) { - return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + wlr_surface_send_frame_done(cursor->surface, &now); + } } static void output_cursor_handle_commit(struct wl_listener *listener, void *data) { struct wlr_output_cursor *cursor = wl_container_of(listener, cursor, surface_commit); - struct wlr_surface *surface = data; - output_cursor_commit(cursor); - - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - - struct wlr_frame_callback *cb, *cnext; - wl_list_for_each_safe(cb, cnext, &surface->current->frame_callback_list, - link) { - wl_callback_send_done(cb->resource, timespec_to_msec(&now)); - wl_resource_destroy(cb->resource); - } } static void output_cursor_handle_destroy(struct wl_listener *listener, diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 8cc2aa33..ad0c6f68 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -929,3 +929,17 @@ void wlr_surface_send_leave(struct wlr_surface *surface, } } } + +static inline int64_t timespec_to_msec(const struct timespec *a) { + return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; +} + +void wlr_surface_send_frame_done(struct wlr_surface *surface, + const struct timespec *when) { + struct wlr_frame_callback *cb, *cnext; + wl_list_for_each_safe(cb, cnext, &surface->current->frame_callback_list, + link) { + wl_callback_send_done(cb->resource, timespec_to_msec(when)); + wl_resource_destroy(cb->resource); + } +} -- cgit v1.2.3 From 17d9e2ce3508d21ccdc9907b02d127b47a4a21bb Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 21 Nov 2017 09:50:00 +0100 Subject: Unify view events naming, remove client from event structs --- include/rootston/view.h | 4 +- include/wlr/types/wlr_wl_shell.h | 10 ++--- include/wlr/types/wlr_xdg_shell_v6.h | 7 +-- rootston/wl_shell.c | 30 ++++++------- types/wlr_wl_shell.c | 87 +++++++++++------------------------- types/wlr_xdg_shell_v6.c | 28 ++++-------- 6 files changed, 55 insertions(+), 111 deletions(-) (limited to 'include') diff --git a/include/rootston/view.h b/include/rootston/view.h index 44a98115..5901f0a5 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -12,8 +12,8 @@ struct roots_wl_shell_surface { struct wl_listener destroy; struct wl_listener request_move; struct wl_listener request_resize; - struct wl_listener request_set_maximized; - struct wl_listener request_set_fullscreen; + struct wl_listener request_maximize; + struct wl_listener request_fullscreen; struct wl_listener set_state; struct wl_listener surface_commit; diff --git a/include/wlr/types/wlr_wl_shell.h b/include/wlr/types/wlr_wl_shell.h index 24936a34..ec087693 100644 --- a/include/wlr/types/wlr_wl_shell.h +++ b/include/wlr/types/wlr_wl_shell.h @@ -81,8 +81,8 @@ struct wlr_wl_shell_surface { struct wl_signal request_move; struct wl_signal request_resize; - struct wl_signal request_set_fullscreen; - struct wl_signal request_set_maximized; + struct wl_signal request_fullscreen; + struct wl_signal request_maximize; struct wl_signal set_state; struct wl_signal set_title; @@ -93,14 +93,12 @@ struct wlr_wl_shell_surface { }; struct wlr_wl_shell_surface_move_event { - struct wl_client *client; struct wlr_wl_shell_surface *surface; struct wlr_seat_client *seat; uint32_t serial; }; struct wlr_wl_shell_surface_resize_event { - struct wl_client *client; struct wlr_wl_shell_surface *surface; struct wlr_seat_client *seat; uint32_t serial; @@ -108,15 +106,13 @@ struct wlr_wl_shell_surface_resize_event { }; struct wlr_wl_shell_surface_set_fullscreen_event { - struct wl_client *client; struct wlr_wl_shell_surface *surface; enum wl_shell_surface_fullscreen_method method; uint32_t framerate; struct wlr_output *output; }; -struct wlr_wl_shell_surface_set_maximized_event { - struct wl_client *client; +struct wlr_wl_shell_surface_maximize_event { struct wlr_wl_shell_surface *surface; struct wlr_output *output; }; diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 7940deef..7e89ec74 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -138,14 +138,12 @@ struct wlr_xdg_surface_v6 { }; struct wlr_xdg_toplevel_v6_move_event { - struct wl_client *client; struct wlr_xdg_surface_v6 *surface; struct wlr_seat_client *seat; uint32_t serial; }; struct wlr_xdg_toplevel_v6_resize_event { - struct wl_client *client; struct wlr_xdg_surface_v6 *surface; struct wlr_seat_client *seat; uint32_t serial; @@ -153,19 +151,16 @@ struct wlr_xdg_toplevel_v6_resize_event { }; struct wlr_xdg_toplevel_v6_set_fullscreen_event { - struct wl_client *client; struct wlr_xdg_surface_v6 *surface; bool fullscreen; struct wlr_output *output; }; struct wlr_xdg_toplevel_v6_show_window_menu_event { - struct wl_client *client; struct wlr_xdg_surface_v6 *surface; struct wlr_seat_client *seat; uint32_t serial; - uint32_t x; - uint32_t y; + uint32_t x, y; }; struct wlr_xdg_shell_v6 *wlr_xdg_shell_v6_create(struct wl_display *display); diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index e69f2dd9..ce568355 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -50,23 +50,21 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { roots_seat_begin_resize(seat, view, e->edges); } -static void handle_request_set_maximized(struct wl_listener *listener, +static void handle_request_maximize(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, request_set_maximized); + wl_container_of(listener, roots_surface, request_maximize); struct roots_view *view = roots_surface->view; - //struct wlr_wl_shell_surface_set_maximized_event *e = data; + //struct wlr_wl_shell_surface_maximize_event *e = data; view_maximize(view, true); } -static void handle_request_set_fullscreen(struct wl_listener *listener, +static void handle_request_fullscreen(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, request_set_fullscreen); + wl_container_of(listener, roots_surface, request_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); } @@ -95,8 +93,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&roots_surface->destroy.link); 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->request_maximize.link); + wl_list_remove(&roots_surface->request_fullscreen.link); wl_list_remove(&roots_surface->set_state.link); wl_list_remove(&roots_surface->surface_commit.link); wl_list_remove(&roots_surface->view->link); @@ -125,13 +123,13 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { roots_surface->request_resize.notify = handle_request_resize; wl_signal_add(&surface->events.request_resize, &roots_surface->request_resize); - 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->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); 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/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index abe967d7..6174c872 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -108,25 +108,17 @@ static void shell_surface_protocol_pong(struct wl_client *client, static void shell_surface_protocol_move(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial) { - wlr_log(L_DEBUG, "got shell surface move"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); - struct wlr_wl_shell_surface_move_event *event = - calloc(1, sizeof(struct wlr_wl_shell_surface_move_event)); - if (event == NULL) { - wl_client_post_no_memory(client); - return; - } - event->client = client; - event->surface = surface; - event->seat = seat; - event->serial = serial; + struct wlr_wl_shell_surface_move_event event = { + .surface = surface, + .seat = seat, + .serial = serial, + }; - wl_signal_emit(&surface->events.request_move, event); - - free(event); + wl_signal_emit(&surface->events.request_move, &event); } static struct wlr_wl_shell_popup_grab *shell_popup_grab_from_seat( @@ -174,26 +166,18 @@ static void shell_surface_destroy_popup_state( static void shell_surface_protocol_resize(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, enum wl_shell_surface_resize edges) { - wlr_log(L_DEBUG, "got shell surface resize"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); - struct wlr_wl_shell_surface_resize_event *event = - calloc(1, sizeof(struct wlr_wl_shell_surface_resize_event)); - if (event == NULL) { - wl_client_post_no_memory(client); - return; - } - event->client = client; - event->surface = surface; - event->seat = seat; - event->serial = serial; - event->edges = edges; + struct wlr_wl_shell_surface_resize_event event = { + .surface = surface, + .seat = seat, + .serial = serial, + .edges = edges, + }; - wl_signal_emit(&surface->events.request_resize, event); - - free(event); + wl_signal_emit(&surface->events.request_resize, &event); } static void shell_surface_set_state(struct wlr_wl_shell_surface *surface, @@ -279,7 +263,6 @@ static void shell_surface_protocol_set_fullscreen(struct wl_client *client, struct wl_resource *resource, enum wl_shell_surface_fullscreen_method method, uint32_t framerate, struct wl_resource *output_resource) { - wlr_log(L_DEBUG, "got shell surface fullscreen"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); struct wlr_output *output = NULL; if (output_resource != NULL) { @@ -289,24 +272,16 @@ static void shell_surface_protocol_set_fullscreen(struct wl_client *client, shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN, NULL, NULL); - struct wlr_wl_shell_surface_set_fullscreen_event *event = - calloc(1, sizeof(struct wlr_wl_shell_surface_set_fullscreen_event)); - if (event == NULL) { - wl_client_post_no_memory(client); - return; - } - event->client = client; - event->surface = surface; - event->method = method; - event->framerate = framerate; - event->output = output; + struct wlr_wl_shell_surface_set_fullscreen_event event = { + .surface = surface, + .method = method, + .framerate = framerate, + .output = output, + }; - wl_signal_emit(&surface->events.request_set_fullscreen, event); - - free(event); + wl_signal_emit(&surface->events.request_fullscreen, &event); } - static void shell_surface_protocol_set_popup(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, struct wl_resource *parent_resource, int32_t x, @@ -368,7 +343,6 @@ static void shell_surface_protocol_set_popup(struct wl_client *client, static void shell_surface_protocol_set_maximized(struct wl_client *client, struct wl_resource *resource, struct wl_resource *output_resource) { - wlr_log(L_DEBUG, "got shell surface maximized"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); struct wlr_output *output = NULL; if (output_resource != NULL) { @@ -378,19 +352,12 @@ static void shell_surface_protocol_set_maximized(struct wl_client *client, shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED, NULL, NULL); - struct wlr_wl_shell_surface_set_maximized_event *event = - calloc(1, sizeof(struct wlr_wl_shell_surface_set_maximized_event)); - if (event == NULL) { - wl_client_post_no_memory(client); - return; - } - event->client = client; - event->surface = surface; - event->output = output; - - wl_signal_emit(&surface->events.request_set_maximized, event); + struct wlr_wl_shell_surface_maximize_event event = { + .surface = surface, + .output = output, + }; - free(event); + wl_signal_emit(&surface->events.request_maximize, &event); } static void shell_surface_protocol_set_title(struct wl_client *client, @@ -545,8 +512,8 @@ static void shell_protocol_get_shell_surface(struct wl_client *client, wl_signal_init(&wl_surface->events.ping_timeout); wl_signal_init(&wl_surface->events.request_move); wl_signal_init(&wl_surface->events.request_resize); - wl_signal_init(&wl_surface->events.request_set_fullscreen); - wl_signal_init(&wl_surface->events.request_set_maximized); + wl_signal_init(&wl_surface->events.request_fullscreen); + wl_signal_init(&wl_surface->events.request_maximize); wl_signal_init(&wl_surface->events.set_state); wl_signal_init(&wl_surface->events.set_title); wl_signal_init(&wl_surface->events.set_class); diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 896a5f33..b69f713e 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -564,23 +564,15 @@ static void xdg_toplevel_protocol_show_window_menu(struct wl_client *client, return; } - struct wlr_xdg_toplevel_v6_show_window_menu_event *event = - calloc(1, sizeof(struct wlr_xdg_toplevel_v6_show_window_menu_event)); - if (event == NULL) { - wl_client_post_no_memory(client); - return; - } - - event->client = client; - event->surface = surface; - event->seat = seat; - event->serial = serial; - event->x = x; - event->y = y; - - wl_signal_emit(&surface->events.request_show_window_menu, event); + struct wlr_xdg_toplevel_v6_show_window_menu_event event = { + .surface = surface, + .seat = seat, + .serial = serial, + .x = x, + .y = y, + }; - free(event); + wl_signal_emit(&surface->events.request_show_window_menu, &event); } static void xdg_toplevel_protocol_move(struct wl_client *client, @@ -598,7 +590,6 @@ static void xdg_toplevel_protocol_move(struct wl_client *client, } struct wlr_xdg_toplevel_v6_move_event event = { - .client = client, .surface = surface, .seat = seat, .serial = serial, @@ -622,7 +613,6 @@ static void xdg_toplevel_protocol_resize(struct wl_client *client, } struct wlr_xdg_toplevel_v6_resize_event event = { - .client = client, .surface = surface, .seat = seat, .serial = serial, @@ -672,7 +662,6 @@ static void xdg_toplevel_protocol_set_fullscreen(struct wl_client *client, surface->toplevel_state->next.fullscreen = true; struct wlr_xdg_toplevel_v6_set_fullscreen_event event = { - .client = client, .surface = surface, .fullscreen = true, .output = output, @@ -688,7 +677,6 @@ static void xdg_toplevel_protocol_unset_fullscreen(struct wl_client *client, surface->toplevel_state->next.fullscreen = false; struct wlr_xdg_toplevel_v6_set_fullscreen_event event = { - .client = client, .surface = surface, .fullscreen = false, .output = NULL, -- cgit v1.2.3 From 9a6f799d8f72c1dcd24e22749d43eb2ed54681c6 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 21 Nov 2017 10:37:53 +0100 Subject: Add fullscreen command, fix view_at with fullscreen views --- include/rootston/desktop.h | 6 +- rootston/cursor.c | 9 ++- rootston/desktop.c | 183 ++++++++++++++++++++++++++------------------- rootston/keyboard.c | 6 ++ 4 files changed, 122 insertions(+), 82 deletions(-) (limited to 'include') diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index 8bf1f6eb..e5c5f806 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -60,11 +60,13 @@ struct roots_server; struct roots_desktop *desktop_create(struct roots_server *server, struct roots_config *config); void desktop_destroy(struct roots_desktop *desktop); +struct roots_output *desktop_output_from_wlr_output( + struct roots_desktop *desktop, struct wlr_output *output); +struct roots_view *desktop_view_at(struct roots_desktop *desktop, double lx, + double ly, struct wlr_surface **surface, double *sx, double *sy); void view_init(struct roots_view *view, struct roots_desktop *desktop); void view_destroy(struct roots_view *view); -struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, - struct wlr_surface **surface, double *sx, double *sy); void view_activate(struct roots_view *view, bool activate); void output_add_notify(struct wl_listener *listener, void *data); diff --git a/rootston/cursor.c b/rootston/cursor.c index 71075aa9..b3c87b30 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -37,7 +37,7 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, double sx, sy; switch (cursor->mode) { case ROOTS_CURSOR_PASSTHROUGH: - view = view_at(desktop, cursor->cursor->x, cursor->cursor->y, + view = desktop_view_at(desktop, cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); bool set_compositor_cursor = !view && cursor->cursor_client; if (view) { @@ -137,7 +137,8 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, struct wlr_surface *surface; double sx, sy; - struct roots_view *view = view_at(desktop, lx, ly, &surface, &sx, &sy); + struct roots_view *view = + desktop_view_at(desktop, lx, ly, &surface, &sx, &sy); if (state == WLR_BUTTON_PRESSED && view && @@ -237,7 +238,7 @@ void roots_cursor_handle_touch_down(struct roots_cursor *cursor, return; } double sx, sy; - view_at(desktop, lx, ly, &surface, &sx, &sy); + desktop_view_at(desktop, lx, ly, &surface, &sx, &sy); uint32_t serial = 0; if (surface) { @@ -291,7 +292,7 @@ void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, } double sx, sy; - view_at(desktop, lx, ly, &surface, &sx, &sy); + desktop_view_at(desktop, lx, ly, &surface, &sx, &sy); if (surface) { wlr_seat_touch_point_focus(cursor->seat->seat, surface, diff --git a/rootston/desktop.c b/rootston/desktop.c index 0eb63dc4..1a21a7c2 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -163,6 +163,11 @@ void view_set_fullscreen(struct roots_view *view, bool fullscreen, if (output == NULL) { output = view_get_output(view); } + struct roots_output *roots_output = + desktop_output_from_wlr_output(view->desktop, output); + if (roots_output == NULL) { + return; + } struct wlr_box view_box; view_get_box(view, &view_box); @@ -179,14 +184,8 @@ void view_set_fullscreen(struct roots_view *view, bool fullscreen, output_box->height); view->rotation = 0; - struct roots_output *roots_output; - wl_list_for_each(roots_output, &view->desktop->outputs, link) { - if (roots_output->wlr_output == output) { - roots_output->fullscreen_view = view; - view->fullscreen_output = roots_output; - break; - } - } + roots_output->fullscreen_view = view; + view->fullscreen_output = roots_output; } if (was_fullscreen && !fullscreen) { @@ -273,83 +272,104 @@ void view_setup(struct roots_view *view) { view_update_output(view, &before); } -struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, +static bool view_at(struct roots_view *view, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { - struct roots_view *view; - wl_list_for_each(view, &desktop->views, link) { - if (view->type == ROOTS_WL_SHELL_VIEW && - view->wl_shell_surface->state == - WLR_WL_SHELL_SURFACE_STATE_POPUP) { - continue; - } + if (view->type == ROOTS_WL_SHELL_VIEW && + view->wl_shell_surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP) { + return false; + } - double view_sx = lx - view->x; - double view_sy = ly - view->y; - - struct wlr_surface_state *state = view->wlr_surface->current; - struct wlr_box box = { - .x = 0, - .y = 0, - .width = state->buffer_width / state->scale, - .height = state->buffer_height / state->scale, - }; - if (view->rotation != 0.0) { - // Coordinates relative to the center of the view - double ox = view_sx - (double)box.width/2, - oy = view_sy - (double)box.height/2; - // Rotated coordinates - double rx = cos(view->rotation)*ox - sin(view->rotation)*oy, - ry = cos(view->rotation)*oy + sin(view->rotation)*ox; - view_sx = rx + (double)box.width/2; - view_sy = ry + (double)box.height/2; - } + double view_sx = lx - view->x; + double view_sy = ly - view->y; + + struct wlr_surface_state *state = view->wlr_surface->current; + struct wlr_box box = { + .x = 0, + .y = 0, + .width = state->buffer_width / state->scale, + .height = state->buffer_height / state->scale, + }; + if (view->rotation != 0.0) { + // Coordinates relative to the center of the view + double ox = view_sx - (double)box.width/2, + oy = view_sy - (double)box.height/2; + // Rotated coordinates + double rx = cos(view->rotation)*ox - sin(view->rotation)*oy, + ry = cos(view->rotation)*oy + sin(view->rotation)*ox; + view_sx = rx + (double)box.width/2; + view_sy = ry + (double)box.height/2; + } - if (view->type == ROOTS_XDG_SHELL_V6_VIEW) { - double popup_sx, popup_sy; - struct wlr_xdg_surface_v6 *popup = - wlr_xdg_surface_v6_popup_at(view->xdg_surface_v6, - view_sx, view_sy, &popup_sx, &popup_sy); - - if (popup) { - *sx = view_sx - popup_sx; - *sy = view_sy - popup_sy; - *surface = popup->surface; - return view; - } + if (view->type == ROOTS_XDG_SHELL_V6_VIEW) { + double popup_sx, popup_sy; + struct wlr_xdg_surface_v6 *popup = + wlr_xdg_surface_v6_popup_at(view->xdg_surface_v6, + view_sx, view_sy, &popup_sx, &popup_sy); + + if (popup) { + *sx = view_sx - popup_sx; + *sy = view_sy - popup_sy; + *surface = popup->surface; + return true; } + } - if (view->type == ROOTS_WL_SHELL_VIEW) { - double popup_sx, popup_sy; - struct wlr_wl_shell_surface *popup = - wlr_wl_shell_surface_popup_at(view->wl_shell_surface, - view_sx, view_sy, &popup_sx, &popup_sy); - - if (popup) { - *sx = view_sx - popup_sx; - *sy = view_sy - popup_sy; - *surface = popup->surface; - return view; - } + if (view->type == ROOTS_WL_SHELL_VIEW) { + double popup_sx, popup_sy; + struct wlr_wl_shell_surface *popup = + wlr_wl_shell_surface_popup_at(view->wl_shell_surface, + view_sx, view_sy, &popup_sx, &popup_sy); + + if (popup) { + *sx = view_sx - popup_sx; + *sy = view_sy - popup_sy; + *surface = popup->surface; + return true; } + } - double sub_x, sub_y; - struct wlr_subsurface *subsurface = - wlr_surface_subsurface_at(view->wlr_surface, - view_sx, view_sy, &sub_x, &sub_y); - if (subsurface) { - *sx = view_sx - sub_x; - *sy = view_sy - sub_y; - *surface = subsurface->surface; - return view; + double sub_x, sub_y; + struct wlr_subsurface *subsurface = + wlr_surface_subsurface_at(view->wlr_surface, + view_sx, view_sy, &sub_x, &sub_y); + if (subsurface) { + *sx = view_sx - sub_x; + *sy = view_sy - sub_y; + *surface = subsurface->surface; + return true; + } + + if (wlr_box_contains_point(&box, view_sx, view_sy) && + pixman_region32_contains_point(&view->wlr_surface->current->input, + view_sx, view_sy, NULL)) { + *sx = view_sx; + *sy = view_sy; + *surface = view->wlr_surface; + return true; + } + + return false; +} + +struct roots_view *desktop_view_at(struct roots_desktop *desktop, double lx, + double ly, struct wlr_surface **surface, double *sx, double *sy) { + struct wlr_output *wlr_output = + wlr_output_layout_output_at(desktop->layout, lx, ly); + if (wlr_output != NULL) { + struct roots_output *output = + desktop_output_from_wlr_output(desktop, wlr_output); + if (output != NULL && output->fullscreen_view != NULL) { + if (view_at(output->fullscreen_view, lx, ly, surface, sx, sy)) { + return output->fullscreen_view; + } else { + return NULL; + } } + } - if (wlr_box_contains_point(&box, view_sx, view_sy) && - pixman_region32_contains_point( - &view->wlr_surface->current->input, - view_sx, view_sy, NULL)) { - *sx = view_sx; - *sy = view_sy; - *surface = view->wlr_surface; + struct roots_view *view; + wl_list_for_each(view, &desktop->views, link) { + if (view_at(view, lx, ly, surface, sx, sy)) { return view; } } @@ -445,3 +465,14 @@ struct roots_desktop *desktop_create(struct roots_server *server, void desktop_destroy(struct roots_desktop *desktop) { // TODO } + +struct roots_output *desktop_output_from_wlr_output( + struct roots_desktop *desktop, struct wlr_output *output) { + struct roots_output *roots_output; + wl_list_for_each(roots_output, &desktop->outputs, link) { + if (roots_output->wlr_output == output) { + return roots_output; + } + } + return NULL; +} diff --git a/rootston/keyboard.c b/rootston/keyboard.c index f3fc9a85..6ad99077 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -95,6 +95,12 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, if (focus != NULL) { view_close(focus); } + } else if (strcmp(command, "fullscreen") == 0) { + struct roots_view *focus = roots_seat_get_focus(seat); + if (focus != NULL) { + bool is_fullscreen = focus->fullscreen_output != NULL; + view_set_fullscreen(focus, !is_fullscreen, NULL); + } } else if (strcmp(command, "next_window") == 0) { roots_seat_cycle_focus(seat); } else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) { -- cgit v1.2.3