Implement damage tracking

This commit is contained in:
Johan Malm 2021-01-09 22:51:20 +00:00
parent 695ce28b55
commit 54804fd3df
15 changed files with 881 additions and 321 deletions

View file

@ -15,6 +15,7 @@ show_menu(struct server *server, const char *menu)
menu_move(server->rootmenu, server->seat.cursor->x,
server->seat.cursor->y);
}
damage_all_outputs(server);
}
void
@ -29,6 +30,7 @@ action(struct server *server, const char *action, const char *command)
} else if (!strcasecmp(action, "Exit")) {
wl_display_terminate(server->wl_display);
} else if (!strcasecmp(action, "NextWindow")) {
dbg_show_views(server);
server->cycle_view =
desktop_cycle_view(server, server->cycle_view);
} else if (!strcasecmp(action, "Reconfigure")) {

View file

@ -66,6 +66,7 @@ request_set_selection_notify(struct wl_listener *listener, void *data)
static void
process_cursor_move(struct server *server, uint32_t time)
{
damage_all_outputs(server);
/* Move the grabbed view to the new position. */
double dx = server->seat.cursor->x - server->grab_x;
double dy = server->seat.cursor->y - server->grab_y;
@ -81,10 +82,7 @@ process_cursor_move(struct server *server, uint32_t time)
static void
process_cursor_resize(struct server *server, uint32_t time)
{
/*
* TODO: Wait for the client to prepare a buffer at the new size, then
* commit any movement that was prepared.
*/
damage_all_outputs(server);
double dx = server->seat.cursor->x - server->grab_x;
double dy = server->seat.cursor->y - server->grab_y;
@ -128,6 +126,7 @@ process_cursor_motion(struct server *server, uint32_t time)
} else if (server->input_mode == LAB_INPUT_STATE_MENU) {
menu_set_selected(server->rootmenu,
server->seat.cursor->x, server->seat.cursor->y);
damage_all_outputs(server);
return;
}
@ -285,6 +284,7 @@ cursor_button(struct wl_listener *listener, void *data)
}
/* Exit interactive move/resize/menu mode. */
server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
damage_all_outputs(server);
return;
}

32
src/damage.c Normal file
View file

@ -0,0 +1,32 @@
#include "labwc.h"
void
damage_all_outputs(struct server *server)
{
struct output *output;
wl_list_for_each(output, &server->outputs, link) {
if (output && output->wlr_output && output->damage) {
wlr_output_damage_add_whole(output->damage);
}
}
}
void
damage_view_part(struct view *view)
{
struct output *output;
wl_list_for_each (output, &view->server->outputs, link) {
output_damage_surface(output, view->surface, view->x, view->y,
false);
}
}
void
damage_view_whole(struct view *view)
{
struct output *output;
wl_list_for_each (output, &view->server->outputs, link) {
output_damage_surface(output, view->surface, view->x, view->y,
true);
}
}

View file

@ -148,6 +148,7 @@ desktop_cycle_view(struct server *server, struct view *current)
do {
view = wl_container_of(view->link.next, view, link);
} while (&view->link == &server->views || !isfocusable(view));
damage_all_outputs(server);
return view;
}

View file

@ -49,6 +49,7 @@ keyboard_key_notify(struct wl_listener *listener, void *data)
wlr_keyboard_get_modifiers(device->keyboard);
if (server->cycle_view) {
damage_all_outputs(server);
if ((syms[0] == XKB_KEY_Alt_L) &&
event->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
/* end cycle */

View file

@ -258,6 +258,7 @@ surface_commit_notify(struct wl_listener *listener, void *data)
wl_container_of(listener, layer, surface_commit);
struct wlr_output *wlr_output = layer->layer_surface->output;
arrange_layers(output_from_wlr_output(layer->server, wlr_output));
damage_all_outputs(layer->server);
}
static void
@ -267,6 +268,7 @@ unmap(struct lab_layer_surface *layer)
if (seat->focused_layer == layer->layer_surface) {
seat_set_focus_layer(seat, NULL);
}
damage_all_outputs(layer->server);
}
static void

View file

@ -1,6 +1,7 @@
labwc_sources = files(
'action.c',
'cursor.c',
'damage.c',
'deco.c',
'desktop.c',
'interactive.c',

File diff suppressed because it is too large Load diff

View file

@ -39,3 +39,13 @@ view_for_each_surface(struct view *view, wlr_surface_iterator_func_t iterator,
view->impl->for_each_surface(view, iterator, user_data);
}
void
view_for_each_popup(struct view *view, wlr_surface_iterator_func_t iterator,
void *data)
{
if (!view->impl->for_each_popup) {
return;
}
view->impl->for_each_popup(view, iterator, data);
}

View file

@ -52,6 +52,86 @@ xdg_toplevel_decoration(struct wl_listener *listener, void *data)
xdg_deco_request_mode(&xdg_deco->request_mode, wlr_decoration);
}
static void
handle_xdg_popup_commit(struct wl_listener *listener, void *data)
{
struct xdg_popup *popup = wl_container_of(listener, popup, map);
/* TODO */
}
static void
handle_xdg_popup_map(struct wl_listener *listener, void *data)
{
struct xdg_popup *popup = wl_container_of(listener, popup, map);
damage_view_whole(popup->view);
}
static void
handle_xdg_popup_unmap(struct wl_listener *listener, void *data)
{
struct xdg_popup *popup = wl_container_of(listener, popup, unmap);
damage_view_whole(popup->view);
}
static void
handle_xdg_popup_destroy(struct wl_listener *listener, void *data)
{
struct xdg_popup *popup = wl_container_of(listener, popup, destroy);
wl_list_remove(&popup->destroy.link);
wl_list_remove(&popup->commit.link);
wl_list_remove(&popup->map.link);
wl_list_remove(&popup->unmap.link);
wl_list_remove(&popup->new_popup.link);
free(popup);
}
static void xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup);
static void
popup_handle_new_xdg_popup(struct wl_listener *listener, void *data)
{
struct xdg_popup *popup = wl_container_of(listener, popup, new_popup);
struct wlr_xdg_popup *wlr_popup = data;
xdg_popup_create(popup->view, wlr_popup);
}
/*
* We need to pass view to this function for damage tracking.
* TODO: Could we just damage surface or whole output?
* That would allow us to only have one 'handle_new_*'
*/
static void
xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup)
{
struct xdg_popup *popup = calloc(1, sizeof(struct xdg_popup));
if (!popup) {
return;
}
popup->wlr_popup = wlr_popup;
popup->view = view;
popup->destroy.notify = handle_xdg_popup_destroy;
wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy);
popup->commit.notify = handle_xdg_popup_commit;
wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit);
popup->map.notify = handle_xdg_popup_map;
wl_signal_add(&wlr_popup->base->events.map, &popup->map);
popup->unmap.notify = handle_xdg_popup_unmap;
wl_signal_add(&wlr_popup->base->events.unmap, &popup->unmap);
popup->new_popup.notify = popup_handle_new_xdg_popup;
wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup);
}
/* This is merely needed to track damage */
static void
handle_new_xdg_popup(struct wl_listener *listener, void *data)
{
struct view *view = wl_container_of(listener, view, new_popup);
struct wlr_xdg_popup *wlr_popup = data;
xdg_popup_create(view, wlr_popup);
}
static bool
has_ssd(struct view *view)
{
@ -95,6 +175,7 @@ handle_commit(struct wl_listener *listener, void *data)
view->pending_move_resize.configure_serial = 0;
}
}
damage_view_part(view);
}
static void
@ -165,6 +246,7 @@ xdg_toplevel_view_configure(struct view *view, struct wlr_box geo)
} else if (view->pending_move_resize.configure_serial == 0) {
view->x = geo.x;
view->y = geo.y;
damage_all_outputs(view->server);
}
}
@ -173,6 +255,7 @@ xdg_toplevel_view_move(struct view *view, double x, double y)
{
view->x = x;
view->y = y;
damage_all_outputs(view->server);
}
static void
@ -181,6 +264,13 @@ xdg_toplevel_view_close(struct view *view)
wlr_xdg_toplevel_send_close(view->xdg_surface);
}
static void
xdg_toplevel_view_for_each_popup(struct view *view,
wlr_surface_iterator_func_t iterator, void *data)
{
wlr_xdg_surface_for_each_popup(view->xdg_surface, iterator, data);
}
static void
xdg_toplevel_view_for_each_surface(struct view *view,
wlr_surface_iterator_func_t iterator, void *data)
@ -234,12 +324,14 @@ xdg_toplevel_view_map(struct view *view)
view->commit.notify = handle_commit;
desktop_focus_view(&view->server->seat, view);
damage_all_outputs(view->server);
}
static void
xdg_toplevel_view_unmap(struct view *view)
{
view->mapped = false;
damage_all_outputs(view->server);
wl_list_remove(&view->commit.link);
desktop_focus_topmost_mapped_view(view->server);
}
@ -247,6 +339,7 @@ xdg_toplevel_view_unmap(struct view *view)
static const struct view_impl xdg_toplevel_view_impl = {
.configure = xdg_toplevel_view_configure,
.close = xdg_toplevel_view_close,
.for_each_popup = xdg_toplevel_view_for_each_popup,
.for_each_surface = xdg_toplevel_view_for_each_surface,
.map = xdg_toplevel_view_map,
.move = xdg_toplevel_view_move,
@ -277,6 +370,9 @@ xdg_surface_new(struct wl_listener *listener, void *data)
view->destroy.notify = handle_destroy;
wl_signal_add(&xdg_surface->events.destroy, &view->destroy);
view->new_popup.notify = handle_new_xdg_popup;
wl_signal_add(&xdg_surface->events.new_popup, &view->new_popup);
struct wlr_xdg_toplevel *toplevel = xdg_surface->toplevel;
view->request_move.notify = handle_request_move;
wl_signal_add(&toplevel->events.request_move, &view->request_move);

View file

@ -19,6 +19,7 @@ unmanaged_handle_commit(struct wl_listener *listener, void *data)
struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface;
unmanaged->lx = xsurface->x;
unmanaged->ly = xsurface->y;
damage_all_outputs(unmanaged->server);
}
static void
@ -36,7 +37,7 @@ unmanaged_handle_map(struct wl_listener *listener, void *data)
unmanaged->lx = xsurface->x;
unmanaged->ly = xsurface->y;
damage_all_outputs(unmanaged->server);
if (wlr_xwayland_or_surface_wants_focus(xsurface)) {
seat_focus_surface(&unmanaged->server->seat, xsurface->surface);
}
@ -48,6 +49,7 @@ unmanaged_handle_unmap(struct wl_listener *listener, void *data)
struct xwayland_unmanaged *unmanaged =
wl_container_of(listener, unmanaged, unmap);
struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface;
damage_all_outputs(unmanaged->server);
wl_list_remove(&unmanaged->link);
wl_list_remove(&unmanaged->commit.link);

View file

@ -21,6 +21,7 @@ handle_commit(struct wl_listener *listener, void *data)
view->pending_move_resize.height - view->h;
view->pending_move_resize.update_y = false;
}
damage_view_whole(view);
}
static void
@ -56,6 +57,7 @@ handle_request_configure(struct wl_listener *listener, void *data)
struct wlr_xwayland_surface_configure_event *event = data;
wlr_xwayland_surface_configure(view->xwayland_surface, event->x,
event->y, event->width, event->height);
damage_all_outputs(view->server);
}
static void
@ -70,6 +72,7 @@ configure(struct view *view, struct wlr_box geo)
wlr_xwayland_surface_configure(view->xwayland_surface, (int16_t)geo.x,
(int16_t)geo.y, (uint16_t)geo.width,
(uint16_t)geo.height);
damage_all_outputs(view->server);
}
static void
@ -80,18 +83,23 @@ move(struct view *view, double x, double y)
struct wlr_xwayland_surface *s = view->xwayland_surface;
wlr_xwayland_surface_configure(s, (int16_t)x, (int16_t)y,
(uint16_t)s->width, (uint16_t)s->height);
damage_all_outputs(view->server);
}
static void
_close(struct view *view)
{
wlr_xwayland_surface_close(view->xwayland_surface);
damage_all_outputs(view->server);
}
static void
for_each_surface(struct view *view, wlr_surface_iterator_func_t iterator,
void *data)
{
if (!view->surface) {
return;
}
wlr_surface_for_each_surface(view->surface, iterator, data);
}
@ -139,12 +147,14 @@ map(struct view *view)
view->commit.notify = handle_commit;
desktop_focus_view(&view->server->seat, view);
damage_all_outputs(view->server);
}
static void
unmap(struct view *view)
{
view->mapped = false;
damage_all_outputs(view->server);
wl_list_remove(&view->commit.link);
desktop_focus_topmost_mapped_view(view->server);
}