mirror of
https://github.com/labwc/labwc.git
synced 2025-11-02 09:01:47 -05:00
SnapToRegion: Allow for live config updates
This commit is contained in:
parent
550e40b56b
commit
07ee56176d
8 changed files with 99 additions and 29 deletions
|
|
@ -315,7 +315,6 @@ struct output {
|
||||||
struct wlr_box usable_area;
|
struct wlr_box usable_area;
|
||||||
|
|
||||||
struct wl_list regions; /* struct region.link */
|
struct wl_list regions; /* struct region.link */
|
||||||
struct wlr_box regions_usable_area;
|
|
||||||
|
|
||||||
struct lab_data_buffer *osd_buffer;
|
struct lab_data_buffer *osd_buffer;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,43 @@ struct region_overlay {
|
||||||
/* Can be used as a cheap check to detect if there are any regions configured */
|
/* Can be used as a cheap check to detect if there are any regions configured */
|
||||||
bool regions_available(void);
|
bool regions_available(void);
|
||||||
|
|
||||||
void regions_update(struct output *output);
|
/**
|
||||||
|
* regions_reconfigure*() - re-initializes all regions from struct rc.
|
||||||
|
*
|
||||||
|
* - all views are evacuated from the given output (or all of them)
|
||||||
|
* - all output local regions are destroyed
|
||||||
|
* - new output local regions are created from struct rc
|
||||||
|
* - the region geometry is re-calculated
|
||||||
|
*/
|
||||||
|
void regions_reconfigure(struct server *server);
|
||||||
|
void regions_reconfigure_output(struct output *output);
|
||||||
|
|
||||||
|
/* re-calculate the geometry based on usable area */
|
||||||
|
void regions_update_geometry(struct output *output);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark all views which are currently region-tiled to the given output as
|
||||||
|
* evacuated. This means that the view->tiled_region pointer is reset to
|
||||||
|
* NULL but view->tiled_region_evacuate is set to a copy of the region name.
|
||||||
|
*
|
||||||
|
* The next time desktop_arrange_all_views() causes a call to
|
||||||
|
* view_apply_region_geometry() it will try to find a new output and then
|
||||||
|
* search for a region with the same name. If found, view->tiled_region will
|
||||||
|
* be set to the new region and view->tiled_region_evacuate will be free'd.
|
||||||
|
*
|
||||||
|
* If no region with the old name is found (e.g. the user deleted or renamed
|
||||||
|
* the region in rc.xml and caused a Reconfigure) the view will be reset to
|
||||||
|
* non-tiled state and view->tiled_region_evacuate will be free'd.
|
||||||
|
*/
|
||||||
void regions_evacuate_output(struct output *output);
|
void regions_evacuate_output(struct output *output);
|
||||||
|
|
||||||
|
/* Free all regions in given wl_list pointer */
|
||||||
void regions_destroy(struct seat *seat, struct wl_list *regions);
|
void regions_destroy(struct seat *seat, struct wl_list *regions);
|
||||||
|
|
||||||
|
/* Get output local region from cursor or name, may be NULL */
|
||||||
struct region *regions_from_cursor(struct server *server);
|
struct region *regions_from_cursor(struct server *server);
|
||||||
struct region *regions_from_name(const char *region_name, struct output *output);
|
struct region *regions_from_name(const char *region_name, struct output *output);
|
||||||
|
|
||||||
void regions_show_overlay(struct view *view, struct seat *seat, struct region *region);
|
void regions_show_overlay(struct view *view, struct seat *seat, struct region *region);
|
||||||
void regions_hide_overlay(struct seat *seat);
|
void regions_hide_overlay(struct seat *seat);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ struct view {
|
||||||
bool maximized;
|
bool maximized;
|
||||||
uint32_t tiled; /* private, enum view_edge in src/view.c */
|
uint32_t tiled; /* private, enum view_edge in src/view.c */
|
||||||
|
|
||||||
/* Pointer to an output owned struct region, may be NULL or already free'd */
|
/* Pointer to an output owned struct region, may be NULL */
|
||||||
struct region *tiled_region;
|
struct region *tiled_region;
|
||||||
/* Set to region->name when tiled_region is free'd by a destroying output */
|
/* Set to region->name when tiled_region is free'd by a destroying output */
|
||||||
char *tiled_region_evacuate;
|
char *tiled_region_evacuate;
|
||||||
|
|
@ -132,6 +132,7 @@ void view_toggle_maximize(struct view *view);
|
||||||
void view_toggle_decorations(struct view *view);
|
void view_toggle_decorations(struct view *view);
|
||||||
void view_toggle_always_on_top(struct view *view);
|
void view_toggle_always_on_top(struct view *view);
|
||||||
bool view_is_always_on_top(struct view *view);
|
bool view_is_always_on_top(struct view *view);
|
||||||
|
bool view_is_tiled(struct view *view);
|
||||||
void view_move_to_workspace(struct view *view, struct workspace *workspace);
|
void view_move_to_workspace(struct view *view, struct workspace *workspace);
|
||||||
void view_set_decorations(struct view *view, bool decorations);
|
void view_set_decorations(struct view *view, bool decorations);
|
||||||
void view_toggle_fullscreen(struct view *view);
|
void view_toggle_fullscreen(struct view *view);
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ interactive_begin(struct view *view, enum input_mode mode, uint32_t edges)
|
||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (view->maximized || view->tiled || view->tiled_region) {
|
if (view->maximized || view_is_tiled(view)) {
|
||||||
/*
|
/*
|
||||||
* Un-maximize and restore natural width/height.
|
* Un-maximize and restore natural width/height.
|
||||||
* Don't reset tiled state yet since we may want
|
* Don't reset tiled state yet since we may want
|
||||||
|
|
|
||||||
|
|
@ -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);
|
output->scene_output = wlr_scene_get_scene_output(server->scene, wlr_output);
|
||||||
assert(output->scene_output);
|
assert(output->scene_output);
|
||||||
|
|
||||||
|
/* Create regions from config */
|
||||||
|
regions_reconfigure_output(output);
|
||||||
|
|
||||||
server->pending_output_layout_change--;
|
server->pending_output_layout_change--;
|
||||||
do_output_layout_change(server);
|
do_output_layout_change(server);
|
||||||
}
|
}
|
||||||
|
|
@ -452,7 +455,7 @@ void
|
||||||
output_update_usable_area(struct output *output)
|
output_update_usable_area(struct output *output)
|
||||||
{
|
{
|
||||||
if (update_usable_area(output)) {
|
if (update_usable_area(output)) {
|
||||||
regions_update(output);
|
regions_update_geometry(output);
|
||||||
desktop_arrange_all_views(output->server);
|
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) {
|
wl_list_for_each(output, &server->outputs, link) {
|
||||||
if (update_usable_area(output)) {
|
if (update_usable_area(output)) {
|
||||||
usable_area_changed = true;
|
usable_area_changed = true;
|
||||||
regions_update(output);
|
regions_update_geometry(output);
|
||||||
} else if (layout_changed) {
|
} else if (layout_changed) {
|
||||||
regions_update(output);
|
regions_update_geometry(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (usable_area_changed || layout_changed) {
|
if (usable_area_changed || layout_changed) {
|
||||||
|
|
|
||||||
|
|
@ -149,15 +149,18 @@ regions_hide_overlay(struct seat *seat)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
regions_update(struct output *output)
|
regions_reconfigure_output(struct output *output)
|
||||||
{
|
{
|
||||||
assert(output);
|
assert(output);
|
||||||
|
|
||||||
struct region *region;
|
/* Evacuate views and destroy current regions */
|
||||||
struct wlr_box usable = output_usable_area_in_layout_coords(output);
|
if (!wl_list_empty(&output->regions)) {
|
||||||
|
regions_evacuate_output(output);
|
||||||
|
regions_destroy(&output->server->seat, &output->regions);
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize regions */
|
/* Initialize regions from config */
|
||||||
if (wl_list_empty(&output->regions)) {
|
struct region *region;
|
||||||
wl_list_for_each(region, &rc.regions, link) {
|
wl_list_for_each(region, &rc.regions, link) {
|
||||||
struct region *region_new = znew(*region_new);
|
struct region *region_new = znew(*region_new);
|
||||||
/* Create a copy */
|
/* Create a copy */
|
||||||
|
|
@ -165,13 +168,32 @@ regions_update(struct output *output)
|
||||||
region_new->percentage = region->percentage;
|
region_new->percentage = region->percentage;
|
||||||
wl_list_append(&output->regions, ®ion_new->link);
|
wl_list_append(&output->regions, ®ion_new->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update region geometries */
|
||||||
|
regions_update_geometry(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlr_box_equal(&output->regions_usable_area, &usable)) {
|
void
|
||||||
/* Nothing changed */
|
regions_reconfigure(struct server *server)
|
||||||
return;
|
{
|
||||||
|
struct output *output;
|
||||||
|
|
||||||
|
/* Evacuate views and initialize regions from config */
|
||||||
|
wl_list_for_each(output, &server->outputs, link) {
|
||||||
|
regions_reconfigure_output(output);
|
||||||
}
|
}
|
||||||
output->regions_usable_area = usable;
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
/* Update regions */
|
/* Update regions */
|
||||||
struct wlr_box *perc, *geo;
|
struct wlr_box *perc, *geo;
|
||||||
|
|
@ -201,6 +223,8 @@ regions_evacuate_output(struct output *output)
|
||||||
view->tiled_region_evacuate =
|
view->tiled_region_evacuate =
|
||||||
xstrdup(region->name);
|
xstrdup(region->name);
|
||||||
}
|
}
|
||||||
|
/* Prevent carrying around a dangling pointer */
|
||||||
|
view->tiled_region = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "layers.h"
|
#include "layers.h"
|
||||||
#include "menu/menu.h"
|
#include "menu/menu.h"
|
||||||
|
#include "regions.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
#include "workspaces.h"
|
#include "workspaces.h"
|
||||||
|
|
@ -49,6 +50,7 @@ reload_config_and_theme(void)
|
||||||
|
|
||||||
menu_reconfigure(g_server);
|
menu_reconfigure(g_server);
|
||||||
seat_reconfigure(g_server);
|
seat_reconfigure(g_server);
|
||||||
|
regions_reconfigure(g_server);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
||||||
18
src/view.c
18
src/view.c
|
|
@ -295,7 +295,7 @@ void
|
||||||
view_store_natural_geometry(struct view *view)
|
view_store_natural_geometry(struct view *view)
|
||||||
{
|
{
|
||||||
assert(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 */
|
/* Do not overwrite the stored geometry with special cases */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -347,7 +347,7 @@ static void
|
||||||
view_apply_region_geometry(struct view *view)
|
view_apply_region_geometry(struct view *view)
|
||||||
{
|
{
|
||||||
assert(view);
|
assert(view);
|
||||||
assert(view->tiled_region);
|
assert(view->tiled_region || view->tiled_region_evacuate);
|
||||||
|
|
||||||
if (view->tiled_region_evacuate) {
|
if (view->tiled_region_evacuate) {
|
||||||
/* View was evacuated from a destroying output */
|
/* View was evacuated from a destroying output */
|
||||||
|
|
@ -357,7 +357,7 @@ view_apply_region_geometry(struct view *view)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get new output local region */
|
/* Get new output local region, may be NULL */
|
||||||
view->tiled_region = regions_from_name(
|
view->tiled_region = regions_from_name(
|
||||||
view->tiled_region_evacuate, output);
|
view->tiled_region_evacuate, output);
|
||||||
|
|
||||||
|
|
@ -500,7 +500,7 @@ view_apply_special_geometry(struct view *view)
|
||||||
view_apply_maximized_geometry(view);
|
view_apply_maximized_geometry(view);
|
||||||
} else if (view->tiled) {
|
} else if (view->tiled) {
|
||||||
view_apply_tiled_geometry(view, NULL);
|
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);
|
view_apply_region_geometry(view);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -538,6 +538,15 @@ view_restore_to(struct view *view, struct wlr_box geometry)
|
||||||
view_move_resize(view, 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 */
|
/* Reset tiled state of view without changing geometry */
|
||||||
void
|
void
|
||||||
view_set_untiled(struct view *view)
|
view_set_untiled(struct view *view)
|
||||||
|
|
@ -545,6 +554,7 @@ view_set_untiled(struct view *view)
|
||||||
assert(view);
|
assert(view);
|
||||||
view->tiled = VIEW_EDGE_INVALID;
|
view->tiled = VIEW_EDGE_INVALID;
|
||||||
view->tiled_region = NULL;
|
view->tiled_region = NULL;
|
||||||
|
zfree(view->tiled_region_evacuate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue