SnapToRegion: Allow for live config updates

This commit is contained in:
Consolatis 2023-01-01 18:12:20 +01:00
parent 550e40b56b
commit 07ee56176d
8 changed files with 99 additions and 29 deletions

View file

@ -45,7 +45,7 @@ interactive_begin(struct view *view, enum input_mode mode, uint32_t edges)
*/
return;
}
if (view->maximized || view->tiled || view->tiled_region) {
if (view->maximized || view_is_tiled(view)) {
/*
* Un-maximize and restore natural width/height.
* Don't reset tiled state yet since we may want

View file

@ -212,6 +212,9 @@ new_output_notify(struct wl_listener *listener, void *data)
output->scene_output = wlr_scene_get_scene_output(server->scene, wlr_output);
assert(output->scene_output);
/* Create regions from config */
regions_reconfigure_output(output);
server->pending_output_layout_change--;
do_output_layout_change(server);
}
@ -452,7 +455,7 @@ void
output_update_usable_area(struct output *output)
{
if (update_usable_area(output)) {
regions_update(output);
regions_update_geometry(output);
desktop_arrange_all_views(output->server);
}
}
@ -466,9 +469,9 @@ output_update_all_usable_areas(struct server *server, bool layout_changed)
wl_list_for_each(output, &server->outputs, link) {
if (update_usable_area(output)) {
usable_area_changed = true;
regions_update(output);
regions_update_geometry(output);
} else if (layout_changed) {
regions_update(output);
regions_update_geometry(output);
}
}
if (usable_area_changed || layout_changed) {

View file

@ -149,30 +149,52 @@ regions_hide_overlay(struct seat *seat)
}
void
regions_update(struct output *output)
regions_reconfigure_output(struct output *output)
{
assert(output);
/* Evacuate views and destroy current regions */
if (!wl_list_empty(&output->regions)) {
regions_evacuate_output(output);
regions_destroy(&output->server->seat, &output->regions);
}
/* Initialize regions from config */
struct region *region;
wl_list_for_each(region, &rc.regions, link) {
struct region *region_new = znew(*region_new);
/* Create a copy */
region_new->name = xstrdup(region->name);
region_new->percentage = region->percentage;
wl_list_append(&output->regions, &region_new->link);
}
/* Update region geometries */
regions_update_geometry(output);
}
void
regions_reconfigure(struct server *server)
{
struct output *output;
/* Evacuate views and initialize regions from config */
wl_list_for_each(output, &server->outputs, link) {
regions_reconfigure_output(output);
}
/* Tries to match the evacuated views to the new regions */
desktop_arrange_all_views(server);
}
void
regions_update_geometry(struct output *output)
{
assert(output);
struct region *region;
struct wlr_box usable = output_usable_area_in_layout_coords(output);
/* Initialize regions */
if (wl_list_empty(&output->regions)) {
wl_list_for_each(region, &rc.regions, link) {
struct region *region_new = znew(*region_new);
/* Create a copy */
region_new->name = xstrdup(region->name);
region_new->percentage = region->percentage;
wl_list_append(&output->regions, &region_new->link);
}
}
if (wlr_box_equal(&output->regions_usable_area, &usable)) {
/* Nothing changed */
return;
}
output->regions_usable_area = usable;
/* Update regions */
struct wlr_box *perc, *geo;
wl_list_for_each(region, &output->regions, link) {
@ -201,6 +223,8 @@ regions_evacuate_output(struct output *output)
view->tiled_region_evacuate =
xstrdup(region->name);
}
/* Prevent carrying around a dangling pointer */
view->tiled_region = NULL;
break;
}
}

View file

@ -20,6 +20,7 @@
#include "labwc.h"
#include "layers.h"
#include "menu/menu.h"
#include "regions.h"
#include "theme.h"
#include "view.h"
#include "workspaces.h"
@ -49,6 +50,7 @@ reload_config_and_theme(void)
menu_reconfigure(g_server);
seat_reconfigure(g_server);
regions_reconfigure(g_server);
}
static int

View file

@ -295,7 +295,7 @@ void
view_store_natural_geometry(struct view *view)
{
assert(view);
if (view->maximized || view->tiled || view->tiled_region) {
if (view->maximized || view_is_tiled(view)) {
/* Do not overwrite the stored geometry with special cases */
return;
}
@ -347,7 +347,7 @@ static void
view_apply_region_geometry(struct view *view)
{
assert(view);
assert(view->tiled_region);
assert(view->tiled_region || view->tiled_region_evacuate);
if (view->tiled_region_evacuate) {
/* View was evacuated from a destroying output */
@ -357,7 +357,7 @@ view_apply_region_geometry(struct view *view)
return;
}
/* Get new output local region */
/* Get new output local region, may be NULL */
view->tiled_region = regions_from_name(
view->tiled_region_evacuate, output);
@ -500,7 +500,7 @@ view_apply_special_geometry(struct view *view)
view_apply_maximized_geometry(view);
} else if (view->tiled) {
view_apply_tiled_geometry(view, NULL);
} else if (view->tiled_region) {
} else if (view->tiled_region || view->tiled_region_evacuate) {
view_apply_region_geometry(view);
} else {
return false;
@ -538,6 +538,15 @@ view_restore_to(struct view *view, struct wlr_box geometry)
view_move_resize(view, geometry);
}
bool
view_is_tiled(struct view *view)
{
if (!view) {
return false;
}
return view->tiled || view->tiled_region || view->tiled_region_evacuate;
}
/* Reset tiled state of view without changing geometry */
void
view_set_untiled(struct view *view)
@ -545,6 +554,7 @@ view_set_untiled(struct view *view)
assert(view);
view->tiled = VIEW_EDGE_INVALID;
view->tiled_region = NULL;
zfree(view->tiled_region_evacuate);
}
void