mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Highlight all child borders when using focus parent
This commit is contained in:
		
							parent
							
								
									fbddd34b47
								
							
						
					
					
						commit
						83e314bf51
					
				
					 2 changed files with 73 additions and 45 deletions
				
			
		| 
						 | 
				
			
			@ -453,7 +453,7 @@ static void render_container_simple_border_pixel(struct sway_output *output,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void render_container(struct sway_output *output,
 | 
			
		||||
	pixman_region32_t *damage, struct sway_container *con);
 | 
			
		||||
	pixman_region32_t *damage, struct sway_container *con, bool parent_focused);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Render a container's children using a L_HORIZ or L_VERT layout.
 | 
			
		||||
| 
						 | 
				
			
			@ -462,7 +462,8 @@ static void render_container(struct sway_output *output,
 | 
			
		|||
 * they'll apply their own borders to their children.
 | 
			
		||||
 */
 | 
			
		||||
static void render_container_simple(struct sway_output *output,
 | 
			
		||||
		pixman_region32_t *damage, struct sway_container *con) {
 | 
			
		||||
		pixman_region32_t *damage, struct sway_container *con,
 | 
			
		||||
		bool parent_focused) {
 | 
			
		||||
	struct sway_seat *seat = input_manager_current_seat(input_manager);
 | 
			
		||||
	struct sway_container *focus = seat_get_focus(seat);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -473,7 +474,7 @@ static void render_container_simple(struct sway_output *output,
 | 
			
		|||
			if (child->sway_view->border != B_NONE) {
 | 
			
		||||
				struct border_colors *colors;
 | 
			
		||||
				struct wlr_texture *title_texture;
 | 
			
		||||
				if (focus == child) {
 | 
			
		||||
				if (focus == child || parent_focused) {
 | 
			
		||||
					colors = &config->border_colors.focused;
 | 
			
		||||
					title_texture = child->title_focused;
 | 
			
		||||
				} else if (seat_get_focus_inactive(seat, con) == child) {
 | 
			
		||||
| 
						 | 
				
			
			@ -494,7 +495,8 @@ static void render_container_simple(struct sway_output *output,
 | 
			
		|||
			}
 | 
			
		||||
			render_view(child->sway_view, output, damage);
 | 
			
		||||
		} else {
 | 
			
		||||
			render_container(output, damage, child);
 | 
			
		||||
			render_container(output, damage, child,
 | 
			
		||||
					parent_focused || focus == child);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -516,12 +518,13 @@ static void render_container_stacked(struct sway_output *output,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void render_container(struct sway_output *output,
 | 
			
		||||
		pixman_region32_t *damage, struct sway_container *con) {
 | 
			
		||||
		pixman_region32_t *damage, struct sway_container *con,
 | 
			
		||||
		bool parent_focused) {
 | 
			
		||||
	switch (con->layout) {
 | 
			
		||||
	case L_NONE:
 | 
			
		||||
	case L_HORIZ:
 | 
			
		||||
	case L_VERT:
 | 
			
		||||
		render_container_simple(output, damage, con);
 | 
			
		||||
		render_container_simple(output, damage, con, parent_focused);
 | 
			
		||||
		break;
 | 
			
		||||
	case L_STACKED:
 | 
			
		||||
		render_container_stacked(output, damage, con);
 | 
			
		||||
| 
						 | 
				
			
			@ -605,7 +608,9 @@ static void render_output(struct sway_output *output, struct timespec *when,
 | 
			
		|||
		render_layer(output, damage,
 | 
			
		||||
			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
 | 
			
		||||
 | 
			
		||||
		render_container(output, damage, workspace);
 | 
			
		||||
		struct sway_seat *seat = input_manager_current_seat(input_manager);
 | 
			
		||||
		struct sway_container *focus = seat_get_focus(seat);
 | 
			
		||||
		render_container(output, damage, workspace, focus == workspace);
 | 
			
		||||
 | 
			
		||||
		render_unmanaged(output, damage,
 | 
			
		||||
			&root_container.sway_root->xwayland_unmanaged);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,27 +65,49 @@ static void seat_container_destroy(struct sway_seat_container *seat_con) {
 | 
			
		|||
	free(seat_con);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void seat_send_focus(struct sway_seat *seat,
 | 
			
		||||
		struct sway_container *con) {
 | 
			
		||||
	if (con->type != C_VIEW) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	struct sway_view *view = con->sway_view;
 | 
			
		||||
	if (view->type == SWAY_VIEW_XWAYLAND) {
 | 
			
		||||
		struct wlr_xwayland *xwayland =
 | 
			
		||||
			seat->input->server->xwayland;
 | 
			
		||||
		wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
 | 
			
		||||
	}
 | 
			
		||||
	view_set_activated(view, true);
 | 
			
		||||
	struct wlr_keyboard *keyboard =
 | 
			
		||||
		wlr_seat_get_keyboard(seat->wlr_seat);
 | 
			
		||||
	if (keyboard) {
 | 
			
		||||
		wlr_seat_keyboard_notify_enter(seat->wlr_seat,
 | 
			
		||||
				view->surface, keyboard->keycodes,
 | 
			
		||||
				keyboard->num_keycodes, &keyboard->modifiers);
 | 
			
		||||
/**
 | 
			
		||||
 * Activate all views within this container recursively.
 | 
			
		||||
 */
 | 
			
		||||
static void seat_send_activate(struct sway_container *con,
 | 
			
		||||
		struct sway_seat *seat) {
 | 
			
		||||
	if (con->type == C_VIEW) {
 | 
			
		||||
		if (!seat_is_input_allowed(seat, con->sway_view->surface)) {
 | 
			
		||||
			wlr_log(L_DEBUG, "Refusing to set focus, input is inhibited");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		view_set_activated(con->sway_view, true);
 | 
			
		||||
	} else {
 | 
			
		||||
		wlr_seat_keyboard_notify_enter(
 | 
			
		||||
				seat->wlr_seat, view->surface, NULL, 0, NULL);
 | 
			
		||||
		for (int i = 0; i < con->children->length; ++i) {
 | 
			
		||||
			struct sway_container *child = con->children->items[i];
 | 
			
		||||
			seat_send_activate(child, seat);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * If con is a view, set it as active and enable keyboard input.
 | 
			
		||||
 * If con is a container, set all child views as active and don't enable
 | 
			
		||||
 * keyboard input on any.
 | 
			
		||||
 */
 | 
			
		||||
static void seat_send_focus(struct sway_container *con,
 | 
			
		||||
		struct sway_seat *seat) {
 | 
			
		||||
	seat_send_activate(con, seat);
 | 
			
		||||
 | 
			
		||||
	if (con->type == C_VIEW
 | 
			
		||||
			&& seat_is_input_allowed(seat, con->sway_view->surface)) {
 | 
			
		||||
		if (con->sway_view->type == SWAY_VIEW_XWAYLAND) {
 | 
			
		||||
			struct wlr_xwayland *xwayland = seat->input->server->xwayland;
 | 
			
		||||
			wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
 | 
			
		||||
		}
 | 
			
		||||
		struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
 | 
			
		||||
		if (keyboard) {
 | 
			
		||||
			wlr_seat_keyboard_notify_enter(seat->wlr_seat,
 | 
			
		||||
					con->sway_view->surface, keyboard->keycodes,
 | 
			
		||||
					keyboard->num_keycodes, &keyboard->modifiers);
 | 
			
		||||
		} else {
 | 
			
		||||
			wlr_seat_keyboard_notify_enter(
 | 
			
		||||
					seat->wlr_seat, con->sway_view->surface, NULL, 0, NULL);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -160,7 +182,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener,
 | 
			
		|||
		// the structure change might have caused it to move up to the top of
 | 
			
		||||
		// the focus stack without sending focus notifications to the view
 | 
			
		||||
		if (seat_get_focus(seat) == next_focus) {
 | 
			
		||||
			seat_send_focus(seat, next_focus);
 | 
			
		||||
			seat_send_focus(next_focus, seat);
 | 
			
		||||
		} else {
 | 
			
		||||
			seat_set_focus(seat, next_focus);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -457,6 +479,20 @@ bool seat_is_input_allowed(struct sway_seat *seat,
 | 
			
		|||
	return !seat->exclusive_client || seat->exclusive_client == client;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unfocus the container and any children (eg. when leaving `focus parent`)
 | 
			
		||||
static void seat_send_unfocus(struct sway_container *container,
 | 
			
		||||
		struct sway_seat *seat) {
 | 
			
		||||
	if (container->type == C_VIEW) {
 | 
			
		||||
		wlr_seat_keyboard_clear_focus(seat->wlr_seat);
 | 
			
		||||
		view_set_activated(container->sway_view, false);
 | 
			
		||||
	} else {
 | 
			
		||||
		for (int i = 0; i < container->children->length; ++i) {
 | 
			
		||||
			struct sway_container *child = container->children->items[i];
 | 
			
		||||
			seat_send_unfocus(child, seat);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void seat_set_focus_warp(struct sway_seat *seat,
 | 
			
		||||
		struct sway_container *container, bool warp) {
 | 
			
		||||
	if (seat->focused_layer) {
 | 
			
		||||
| 
						 | 
				
			
			@ -521,15 +557,11 @@ void seat_set_focus_warp(struct sway_seat *seat,
 | 
			
		|||
		wl_list_remove(&seat_con->link);
 | 
			
		||||
		wl_list_insert(&seat->focus_stack, &seat_con->link);
 | 
			
		||||
 | 
			
		||||
		if (container->type == C_VIEW && !seat_is_input_allowed(
 | 
			
		||||
					seat, container->sway_view->surface)) {
 | 
			
		||||
			wlr_log(L_DEBUG, "Refusing to set focus, input is inhibited");
 | 
			
		||||
			return;
 | 
			
		||||
		if (last_focus) {
 | 
			
		||||
			seat_send_unfocus(last_focus, seat);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (container->type == C_VIEW) {
 | 
			
		||||
			seat_send_focus(seat, container);
 | 
			
		||||
		}
 | 
			
		||||
		seat_send_focus(container, seat);
 | 
			
		||||
		container_damage_whole(container);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -580,12 +612,6 @@ void seat_set_focus_warp(struct sway_seat *seat,
 | 
			
		|||
		container_damage_whole(last_focus);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (last_focus && last_focus->type == C_VIEW &&
 | 
			
		||||
			!input_manager_has_focus(seat->input, last_focus)) {
 | 
			
		||||
		struct sway_view *view = last_focus->sway_view;
 | 
			
		||||
		view_set_activated(view, false);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (last_workspace && last_workspace != new_workspace) {
 | 
			
		||||
		cursor_send_pointer_motion(seat->cursor, 0);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -607,10 +633,7 @@ void seat_set_focus_surface(struct sway_seat *seat,
 | 
			
		|||
	}
 | 
			
		||||
	if (seat->has_focus) {
 | 
			
		||||
		struct sway_container *focus = seat_get_focus(seat);
 | 
			
		||||
		if (focus->type == C_VIEW) {
 | 
			
		||||
			wlr_seat_keyboard_clear_focus(seat->wlr_seat);
 | 
			
		||||
			view_set_activated(focus->sway_view, false);
 | 
			
		||||
		}
 | 
			
		||||
		seat_send_unfocus(focus, seat);
 | 
			
		||||
		seat->has_focus = false;
 | 
			
		||||
	}
 | 
			
		||||
	struct wlr_keyboard *keyboard =
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue