mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -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,30 +149,52 @@ regions_hide_overlay(struct seat *seat)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					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, ®ion_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);
 | 
						assert(output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct region *region;
 | 
						struct region *region;
 | 
				
			||||||
	struct wlr_box usable = output_usable_area_in_layout_coords(output);
 | 
						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, ®ion_new->link);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (wlr_box_equal(&output->regions_usable_area, &usable)) {
 | 
					 | 
				
			||||||
		/* Nothing changed */
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	output->regions_usable_area = usable;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Update regions */
 | 
						/* Update regions */
 | 
				
			||||||
	struct wlr_box *perc, *geo;
 | 
						struct wlr_box *perc, *geo;
 | 
				
			||||||
	wl_list_for_each(region, &output->regions, link) {
 | 
						wl_list_for_each(region, &output->regions, link) {
 | 
				
			||||||
| 
						 | 
					@ -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