[fixup] remove overlay.pending and add overlay.active.output

This commit is contained in:
tokyo4j 2024-03-24 22:24:40 +09:00
parent 5b1a03ae69
commit 93bc17a99a
7 changed files with 50 additions and 48 deletions

View file

@ -160,7 +160,6 @@ struct seat {
struct wlr_scene_tree *icons; struct wlr_scene_tree *icons;
} drag; } drag;
/* Private use by overlay.c */
struct overlay overlay; struct overlay overlay;
/* Used to prevent region snapping when starting a move with A-Left */ /* Used to prevent region snapping when starting a move with A-Left */
bool region_prevent_snap; bool region_prevent_snap;

View file

@ -14,23 +14,23 @@ struct overlay {
struct multi_rect *pixman_rect; struct multi_rect *pixman_rect;
}; };
/* For caching previously shown overlay */ /* Represents currently shown or delayed overlay */
struct { struct {
/* Region overlay */
struct region *region; struct region *region;
/* Snap-to-edge overlay */
enum view_edge edge; enum view_edge edge;
struct output *output;
} active; } active;
/* For delayed snap-to-edge overlay */ /* For delayed snap-to-edge overlay */
struct wl_event_source *timer; struct wl_event_source *timer;
struct {
struct view *view;
struct wlr_box box;
} pending;
}; };
/* Calls overlay_hide() internally if the view is not to be snapped */ /* Calls overlay_hide() internally if there's no overlay to show */
void overlay_show(struct seat *seat, struct view *view); void overlay_show(struct seat *seat);
/* This function must be called when grabbed view is destroyed */ /* This function must be called when server->grabbed_view is destroyed */
void overlay_hide(struct seat *seat); void overlay_hide(struct seat *seat);
#endif #endif

View file

@ -225,7 +225,7 @@ process_cursor_move(struct server *server, uint32_t time)
resistance_move_apply(view, &dx, &dy); resistance_move_apply(view, &dx, &dy);
view_move(view, dx, dy); view_move(view, dx, dy);
overlay_show(&server->seat, view); overlay_show(&server->seat);
} }
static void static void

View file

@ -80,6 +80,8 @@ keyboard_modifiers_notify(struct wl_listener *listener, void *data)
if (server->input_mode == LAB_INPUT_STATE_MOVE) { if (server->input_mode == LAB_INPUT_STATE_MOVE) {
/* Any change to the modifier state re-enable region snap */ /* Any change to the modifier state re-enable region snap */
seat->region_prevent_snap = false; seat->region_prevent_snap = false;
/* Pressing/releasing modifier key may show/hide region overlay */
overlay_show(seat);
} }
if (server->osd_state.cycle_view if (server->osd_state.cycle_view
@ -97,10 +99,6 @@ keyboard_modifiers_notify(struct wl_listener *listener, void *data)
} }
} }
} }
/* Pressing/releasing modifier key may show/hide region overlay */
if (server->grabbed_view) {
overlay_show(seat, server->grabbed_view);
}
if (!input_method_keyboard_grab_forward_modifiers(keyboard)) { if (!input_method_keyboard_grab_forward_modifiers(keyboard)) {
wlr_seat_keyboard_notify_modifiers(seat->seat, wlr_seat_keyboard_notify_modifiers(seat->seat,

View file

@ -102,13 +102,17 @@ static void
output_destroy_notify(struct wl_listener *listener, void *data) output_destroy_notify(struct wl_listener *listener, void *data)
{ {
struct output *output = wl_container_of(listener, output, destroy); struct output *output = wl_container_of(listener, output, destroy);
struct seat *seat = &output->server->seat;
regions_evacuate_output(output); regions_evacuate_output(output);
regions_destroy(&output->server->seat, &output->regions); regions_destroy(seat, &output->regions);
if (seat->overlay.active.output == output) {
overlay_hide(seat);
}
wl_list_remove(&output->link); wl_list_remove(&output->link);
wl_list_remove(&output->frame.link); wl_list_remove(&output->frame.link);
wl_list_remove(&output->destroy.link); wl_list_remove(&output->destroy.link);
wl_list_remove(&output->request_state.link); wl_list_remove(&output->request_state.link);
seat_output_layout_changed(&output->server->seat); seat_output_layout_changed(seat);
for (size_t i = 0; i < ARRAY_SIZE(output->layer_tree); i++) { for (size_t i = 0; i < ARRAY_SIZE(output->layer_tree); i++) {
wlr_scene_node_destroy(&output->layer_tree[i]->node); wlr_scene_node_destroy(&output->layer_tree[i]->node);

View file

@ -32,24 +32,16 @@ create_overlay(struct seat *seat)
} }
static void static void
cancel_pending_overlay(struct overlay *overlay) show_overlay(struct seat *seat, struct wlr_box *box)
{ {
if (overlay->timer) { struct server *server = seat->server;
wl_event_source_timer_update(overlay->timer, 0); struct view *view = server->grabbed_view;
} assert(view);
overlay->pending.view = NULL;
overlay->pending.box = (struct wlr_box){0};
}
static void
show_overlay(struct seat *seat, struct view *view, struct wlr_box *box)
{
if (!seat->overlay.tree) { if (!seat->overlay.tree) {
create_overlay(seat); create_overlay(seat);
} }
/* Update overlay */
struct server *server = seat->server;
struct wlr_scene_node *node = &seat->overlay.tree->node; struct wlr_scene_node *node = &seat->overlay.tree->node;
if (!wlr_renderer_is_pixman(server->renderer)) { if (!wlr_renderer_is_pixman(server->renderer)) {
/* Hardware assisted rendering: Half transparent overlay */ /* Hardware assisted rendering: Half transparent overlay */
@ -66,19 +58,22 @@ show_overlay(struct seat *seat, struct view *view, struct wlr_box *box)
} }
wlr_scene_node_set_position(node, box->x, box->y); wlr_scene_node_set_position(node, box->x, box->y);
wlr_scene_node_set_enabled(node, true); wlr_scene_node_set_enabled(node, true);
cancel_pending_overlay(&seat->overlay);
} }
static void static void
show_region_overlay(struct seat *seat, struct view *view, struct region *region) show_region_overlay(struct seat *seat, struct region *region)
{ {
if (region == seat->overlay.active.region) { if (region == seat->overlay.active.region) {
return; return;
} }
seat->overlay.active.region = region; seat->overlay.active.region = region;
seat->overlay.active.edge = VIEW_EDGE_INVALID; seat->overlay.active.edge = VIEW_EDGE_INVALID;
show_overlay(seat, view, &region->geo); seat->overlay.active.output = NULL;
if (seat->overlay.timer) {
wl_event_source_timer_update(seat->overlay.timer, 0);
}
show_overlay(seat, &region->geo);
} }
/* TODO: share logic with view_get_edge_snap_box() */ /* TODO: share logic with view_get_edge_snap_box() */
@ -109,37 +104,40 @@ static struct wlr_box get_edge_snap_box(enum view_edge edge, struct output *outp
} }
static int static int
handle_overlay_timeout(void *data) handle_edge_overlay_timeout(void *data)
{ {
struct seat *seat = data; struct seat *seat = data;
show_overlay(seat, seat->overlay.pending.view, assert(seat->overlay.active.edge != VIEW_EDGE_INVALID
&seat->overlay.pending.box); && seat->overlay.active.output);
struct wlr_box box = get_edge_snap_box(seat->overlay.active.edge,
seat->overlay.active.output);
show_overlay(seat, &box);
return 0; return 0;
} }
static void static void
show_edge_overlay_delayed(struct seat *seat, struct view *view, show_edge_overlay_delayed(struct seat *seat, enum view_edge edge,
enum view_edge edge, struct output *output) struct output *output)
{ {
if (seat->overlay.active.edge == edge) { if (seat->overlay.active.edge == edge
&& seat->overlay.active.output == output) {
return; return;
} }
seat->overlay.active.edge = edge;
seat->overlay.active.region = NULL; seat->overlay.active.region = NULL;
seat->overlay.active.edge = edge;
seat->overlay.active.output = output;
seat->overlay.pending.view = view;
seat->overlay.pending.box = get_edge_snap_box(edge, output);
if (!seat->overlay.timer) { if (!seat->overlay.timer) {
seat->overlay.timer = wl_event_loop_add_timer( seat->overlay.timer = wl_event_loop_add_timer(
seat->server->wl_event_loop, seat->server->wl_event_loop,
handle_overlay_timeout, seat); handle_edge_overlay_timeout, seat);
} }
/* Delay for 150ms */ /* Delay for 150ms */
wl_event_source_timer_update(seat->overlay.timer, 150); wl_event_source_timer_update(seat->overlay.timer, 150);
} }
void void
overlay_show(struct seat *seat, struct view *view) overlay_show(struct seat *seat)
{ {
struct server *server = seat->server; struct server *server = seat->server;
@ -147,7 +145,7 @@ overlay_show(struct seat *seat, struct view *view)
if (regions_should_snap(server)) { if (regions_should_snap(server)) {
struct region *region = regions_from_cursor(server); struct region *region = regions_from_cursor(server);
if (region) { if (region) {
show_region_overlay(seat, view, region); show_region_overlay(seat, region);
return; return;
} }
} }
@ -161,7 +159,7 @@ overlay_show(struct seat *seat, struct view *view)
* flickering when dragging view across output edges in * flickering when dragging view across output edges in
* multi-monitor setup. * multi-monitor setup.
*/ */
show_edge_overlay_delayed(seat, view, edge, output); show_edge_overlay_delayed(seat, edge, output);
return; return;
} }
@ -171,9 +169,12 @@ overlay_show(struct seat *seat, struct view *view)
void void
overlay_hide(struct seat *seat) overlay_hide(struct seat *seat)
{ {
cancel_pending_overlay(&seat->overlay);
seat->overlay.active.edge = VIEW_EDGE_INVALID;
seat->overlay.active.region = NULL; seat->overlay.active.region = NULL;
seat->overlay.active.edge = VIEW_EDGE_INVALID;
seat->overlay.active.output = NULL;
if (seat->overlay.timer) {
wl_event_source_timer_update(seat->overlay.timer, 0);
}
if (!seat->overlay.tree) { if (!seat->overlay.tree) {
return; return;

View file

@ -164,7 +164,7 @@ regions_destroy(struct seat *seat, struct wl_list *regions)
wl_list_for_each_safe(region, region_tmp, regions, link) { wl_list_for_each_safe(region, region_tmp, regions, link) {
wl_list_remove(&region->link); wl_list_remove(&region->link);
if (seat && seat->overlay.active.region == region) { if (seat && seat->overlay.active.region == region) {
seat->overlay.active.region = NULL; overlay_hide(seat);
} }
zfree(region->name); zfree(region->name);
zfree(region); zfree(region);