mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	view: Tidy up view->output/view->fullscreen redundancy
A fullscreen view currently has its output specified twice by:
  - struct output *output
  - struct wlr_output *fullscreen
view->fullscreen may also become a dangling pointer if the output is
disconnected, because view_on_output_destroy() clears view->output but
not view->fullscreen.
To eliminate the redundancy and the dangling pointer, let's change
view->fullscreen to a Boolean and rely on view->output to specify the
output.
Along the way, change a few related usages of struct wlr_output to
struct output as well.
No functional change intended.
v2: Don't allow entering fullscreen on disabled output (makes
    conditions for entering/leaving fullscreen symmetric)
v3: Use output_is_usable() helper
			
			
This commit is contained in:
		
							parent
							
								
									6efc6a9db4
								
							
						
					
					
						commit
						49c9466039
					
				
					 3 changed files with 44 additions and 47 deletions
				
			
		| 
						 | 
					@ -48,6 +48,7 @@ struct view {
 | 
				
			||||||
	bool ssd_enabled;
 | 
						bool ssd_enabled;
 | 
				
			||||||
	bool minimized;
 | 
						bool minimized;
 | 
				
			||||||
	bool maximized;
 | 
						bool maximized;
 | 
				
			||||||
 | 
						bool fullscreen;
 | 
				
			||||||
	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 */
 | 
						/* Pointer to an output owned struct region, may be NULL */
 | 
				
			||||||
| 
						 | 
					@ -55,8 +56,6 @@ struct view {
 | 
				
			||||||
	/* 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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_output *fullscreen;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Geometry of the wlr_surface contained within the view, as
 | 
						 * Geometry of the wlr_surface contained within the view, as
 | 
				
			||||||
	 * currently displayed. Should be kept in sync with the
 | 
						 * currently displayed. Should be kept in sync with the
 | 
				
			||||||
| 
						 | 
					@ -137,7 +136,7 @@ void view_set_untiled(struct view *view);
 | 
				
			||||||
void view_maximize(struct view *view, bool maximize,
 | 
					void view_maximize(struct view *view, bool maximize,
 | 
				
			||||||
	bool store_natural_geometry);
 | 
						bool store_natural_geometry);
 | 
				
			||||||
void view_set_fullscreen(struct view *view, bool fullscreen,
 | 
					void view_set_fullscreen(struct view *view, bool fullscreen,
 | 
				
			||||||
	struct wlr_output *wlr_output);
 | 
						struct output *output);
 | 
				
			||||||
void view_toggle_maximize(struct view *view);
 | 
					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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										78
									
								
								src/view.c
									
										
									
									
									
								
							
							
						
						
									
										78
									
								
								src/view.c
									
										
									
									
									
								
							| 
						 | 
					@ -221,9 +221,9 @@ view_minimize(struct view *view, bool minimized)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* view_wlr_output - return the output that a view is mostly on */
 | 
					/* view_output - return the output that a view is mostly on */
 | 
				
			||||||
static struct wlr_output *
 | 
					static struct output *
 | 
				
			||||||
view_wlr_output(struct view *view)
 | 
					view_output(struct view *view)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	assert(view);
 | 
						assert(view);
 | 
				
			||||||
	double closest_x, closest_y;
 | 
						double closest_x, closest_y;
 | 
				
			||||||
| 
						 | 
					@ -234,13 +234,6 @@ view_wlr_output(struct view *view)
 | 
				
			||||||
		&closest_x, &closest_y);
 | 
							&closest_x, &closest_y);
 | 
				
			||||||
	wlr_output = wlr_output_layout_output_at(view->server->output_layout,
 | 
						wlr_output = wlr_output_layout_output_at(view->server->output_layout,
 | 
				
			||||||
		closest_x, closest_y);
 | 
							closest_x, closest_y);
 | 
				
			||||||
	return wlr_output;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct output *
 | 
					 | 
				
			||||||
view_output(struct view *view)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct wlr_output *wlr_output = view_wlr_output(view);
 | 
					 | 
				
			||||||
	return output_from_wlr_output(view->server, wlr_output);
 | 
						return output_from_wlr_output(view->server, wlr_output);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -442,16 +435,17 @@ view_apply_tiled_geometry(struct view *view, struct output *output)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
view_apply_fullscreen_geometry(struct view *view, struct wlr_output *wlr_output)
 | 
					view_apply_fullscreen_geometry(struct view *view)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	assert(wlr_output);
 | 
						assert(view->fullscreen);
 | 
				
			||||||
	struct output *output =
 | 
						assert(output_is_usable(view->output));
 | 
				
			||||||
		output_from_wlr_output(view->server, wlr_output);
 | 
					
 | 
				
			||||||
	struct wlr_box box = { 0 };
 | 
						struct wlr_box box = { 0 };
 | 
				
			||||||
	wlr_output_effective_resolution(wlr_output, &box.width, &box.height);
 | 
						wlr_output_effective_resolution(view->output->wlr_output,
 | 
				
			||||||
 | 
							&box.width, &box.height);
 | 
				
			||||||
	double ox = 0, oy = 0;
 | 
						double ox = 0, oy = 0;
 | 
				
			||||||
	wlr_output_layout_output_coords(output->server->output_layout,
 | 
						wlr_output_layout_output_coords(view->server->output_layout,
 | 
				
			||||||
		output->wlr_output, &ox, &oy);
 | 
							view->output->wlr_output, &ox, &oy);
 | 
				
			||||||
	box.x -= ox;
 | 
						box.x -= ox;
 | 
				
			||||||
	box.y -= oy;
 | 
						box.y -= oy;
 | 
				
			||||||
	view_move_resize(view, box);
 | 
						view_move_resize(view, box);
 | 
				
			||||||
| 
						 | 
					@ -679,16 +673,15 @@ view_toggle_fullscreen(struct view *view)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
view_set_fullscreen(struct view *view, bool fullscreen,
 | 
					view_set_fullscreen(struct view *view, bool fullscreen, struct output *output)
 | 
				
			||||||
		struct wlr_output *wlr_output)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	assert(view);
 | 
						assert(view);
 | 
				
			||||||
	if (fullscreen != !view->fullscreen) {
 | 
						if (fullscreen == view->fullscreen) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!wlr_output) {
 | 
						if (fullscreen && !output_is_usable(output)) {
 | 
				
			||||||
		wlr_output = view_wlr_output(view);
 | 
							output = view_output(view);
 | 
				
			||||||
		if (!wlr_output && fullscreen) {
 | 
							if (!output_is_usable(output)) {
 | 
				
			||||||
			/* Prevent fullscreen with no available outputs */
 | 
								/* Prevent fullscreen with no available outputs */
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -713,8 +706,9 @@ view_set_fullscreen(struct view *view, bool fullscreen,
 | 
				
			||||||
		if (view->ssd_enabled) {
 | 
							if (view->ssd_enabled) {
 | 
				
			||||||
			undecorate(view);
 | 
								undecorate(view);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		view->fullscreen = wlr_output;
 | 
							view->fullscreen = true;
 | 
				
			||||||
		view_apply_fullscreen_geometry(view, view->fullscreen);
 | 
							view->output = output;
 | 
				
			||||||
 | 
							view_apply_fullscreen_geometry(view);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		view->fullscreen = false;
 | 
							view->fullscreen = false;
 | 
				
			||||||
		/* Re-show decorations when no longer fullscreen */
 | 
							/* Re-show decorations when no longer fullscreen */
 | 
				
			||||||
| 
						 | 
					@ -728,32 +722,29 @@ view_set_fullscreen(struct view *view, bool fullscreen,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Show fullscreen views above top-layer */
 | 
						/* Show fullscreen views above top-layer */
 | 
				
			||||||
	struct output *output =
 | 
						if (view->output) {
 | 
				
			||||||
		output_from_wlr_output(view->server, wlr_output);
 | 
							uint32_t top = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
 | 
				
			||||||
	if (!output) {
 | 
							wlr_scene_node_set_enabled(&view->output->layer_tree[top]->node,
 | 
				
			||||||
		return;
 | 
								!fullscreen);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	uint32_t top = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
 | 
					 | 
				
			||||||
	wlr_scene_node_set_enabled(&output->layer_tree[top]->node, !fullscreen);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
view_adjust_for_layout_change(struct view *view)
 | 
					view_adjust_for_layout_change(struct view *view)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	assert(view);
 | 
						assert(view);
 | 
				
			||||||
	struct wlr_output_layout *layout = view->server->output_layout;
 | 
					 | 
				
			||||||
	if (view->fullscreen) {
 | 
						if (view->fullscreen) {
 | 
				
			||||||
		if (wlr_output_layout_get(layout, view->fullscreen)) {
 | 
							if (output_is_usable(view->output)) {
 | 
				
			||||||
			/* recompute fullscreen geometry */
 | 
								/* recompute fullscreen geometry */
 | 
				
			||||||
			view_apply_fullscreen_geometry(view, view->fullscreen);
 | 
								view_apply_fullscreen_geometry(view);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			/* output is gone, exit fullscreen */
 | 
								/* output is gone, exit fullscreen */
 | 
				
			||||||
			view_set_fullscreen(view, false, NULL);
 | 
								view_set_fullscreen(view, false, NULL);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (!view_apply_special_geometry(view)) {
 | 
						} else if (!view_apply_special_geometry(view)) {
 | 
				
			||||||
		/* reposition view if it's offscreen */
 | 
							/* reposition view if it's offscreen */
 | 
				
			||||||
		if (!wlr_output_layout_intersects(layout, NULL,
 | 
							if (!wlr_output_layout_intersects(view->server->output_layout,
 | 
				
			||||||
				&view->pending)) {
 | 
									NULL, &view->pending)) {
 | 
				
			||||||
			view_center(view);
 | 
								view_center(view);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -771,7 +762,13 @@ void
 | 
				
			||||||
view_discover_output(struct view *view)
 | 
					view_discover_output(struct view *view)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	assert(view);
 | 
						assert(view);
 | 
				
			||||||
	view->output = view_output(view);
 | 
						/*
 | 
				
			||||||
 | 
						 * Fullscreen views are tied to a particular output so don't
 | 
				
			||||||
 | 
						 * auto-discover output for them.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (!view->fullscreen) {
 | 
				
			||||||
 | 
							view->output = view_output(view);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -1052,11 +1049,10 @@ view_destroy(struct view *view)
 | 
				
			||||||
	 * in fullscreen mode, so if that's the case, we have to re-enable it
 | 
						 * in fullscreen mode, so if that's the case, we have to re-enable it
 | 
				
			||||||
	 * here.
 | 
						 * here.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (view->fullscreen) {
 | 
						if (view->fullscreen && view->output) {
 | 
				
			||||||
		struct output *output =
 | 
					 | 
				
			||||||
			output_from_wlr_output(server, view->fullscreen);
 | 
					 | 
				
			||||||
		uint32_t top = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
 | 
							uint32_t top = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
 | 
				
			||||||
		wlr_scene_node_set_enabled(&output->layer_tree[top]->node, true);
 | 
							wlr_scene_node_set_enabled(&view->output->layer_tree[top]->node,
 | 
				
			||||||
 | 
								true);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If we spawned a window menu, close it */
 | 
						/* If we spawned a window menu, close it */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,8 +178,9 @@ handle_request_fullscreen(struct wl_listener *listener, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct view *view = wl_container_of(listener, view, request_fullscreen);
 | 
						struct view *view = wl_container_of(listener, view, request_fullscreen);
 | 
				
			||||||
	struct wlr_xdg_toplevel *xdg_toplevel = xdg_toplevel_from_view(view);
 | 
						struct wlr_xdg_toplevel *xdg_toplevel = xdg_toplevel_from_view(view);
 | 
				
			||||||
	view_set_fullscreen(view, xdg_toplevel->requested.fullscreen,
 | 
						struct output *output = output_from_wlr_output(view->server,
 | 
				
			||||||
		xdg_toplevel->requested.fullscreen_output);
 | 
							xdg_toplevel->requested.fullscreen_output);
 | 
				
			||||||
 | 
						view_set_fullscreen(view, xdg_toplevel->requested.fullscreen, output);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -345,8 +346,9 @@ xdg_toplevel_view_map(struct view *view)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!view->fullscreen && requested->fullscreen) {
 | 
							if (!view->fullscreen && requested->fullscreen) {
 | 
				
			||||||
			view_set_fullscreen(view, true,
 | 
								struct output *output = output_from_wlr_output(
 | 
				
			||||||
				requested->fullscreen_output);
 | 
									view->server, requested->fullscreen_output);
 | 
				
			||||||
 | 
								view_set_fullscreen(view, true, output);
 | 
				
			||||||
		} else if (!view->maximized && requested->maximized) {
 | 
							} else if (!view->maximized && requested->maximized) {
 | 
				
			||||||
			view_maximize(view, true,
 | 
								view_maximize(view, true,
 | 
				
			||||||
				/*store_natural_geometry*/ true);
 | 
									/*store_natural_geometry*/ true);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue