mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Give keyboard focus to unmanaged xwayland surfaces
This fixes dmenu
This commit is contained in:
		
							parent
							
								
									a5d06b6e2b
								
							
						
					
					
						commit
						2b357af7ee
					
				
					 4 changed files with 58 additions and 36 deletions
				
			
		| 
						 | 
					@ -64,6 +64,9 @@ void seat_set_focus(struct sway_seat *seat, struct sway_container *container);
 | 
				
			||||||
void seat_set_focus_warp(struct sway_seat *seat,
 | 
					void seat_set_focus_warp(struct sway_seat *seat,
 | 
				
			||||||
		struct sway_container *container, bool warp);
 | 
							struct sway_container *container, bool warp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void seat_set_focus_surface(struct sway_seat *seat,
 | 
				
			||||||
 | 
							struct wlr_surface *surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void seat_set_focus_layer(struct sway_seat *seat,
 | 
					void seat_set_focus_layer(struct sway_seat *seat,
 | 
				
			||||||
		struct wlr_layer_surface *layer);
 | 
							struct wlr_layer_surface *layer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,6 +59,13 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	surface->ly = xsurface->y;
 | 
						surface->ly = xsurface->y;
 | 
				
			||||||
	desktop_damage_surface(xsurface->surface, surface->lx, surface->ly, true);
 | 
						desktop_damage_surface(xsurface->surface, surface->lx, surface->ly, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!wlr_xwayland_surface_is_unmanaged(xsurface)) {
 | 
				
			||||||
 | 
							struct sway_seat *seat = input_manager_current_seat(input_manager);
 | 
				
			||||||
 | 
							struct wlr_xwayland *xwayland = seat->input->server->xwayland;
 | 
				
			||||||
 | 
							wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
 | 
				
			||||||
 | 
							seat_set_focus_surface(seat, xsurface->surface);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO: we don't send surface enter/leave events to xwayland unmanaged
 | 
						// TODO: we don't send surface enter/leave events to xwayland unmanaged
 | 
				
			||||||
	// surfaces, but xwayland doesn't support HiDPI anyway
 | 
						// surfaces, but xwayland doesn't support HiDPI anyway
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,7 +84,6 @@ static void seat_send_focus(struct sway_seat *seat,
 | 
				
			||||||
		wlr_seat_keyboard_notify_enter(
 | 
							wlr_seat_keyboard_notify_enter(
 | 
				
			||||||
				seat->wlr_seat, view->surface, NULL, 0, NULL);
 | 
									seat->wlr_seat, view->surface, NULL, 0, NULL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_seat_container_destroy(struct wl_listener *listener,
 | 
					static void handle_seat_container_destroy(struct wl_listener *listener,
 | 
				
			||||||
| 
						 | 
					@ -405,6 +404,8 @@ void seat_set_focus_warp(struct sway_seat *seat,
 | 
				
			||||||
				container_destroy(last_ws);
 | 
									container_destroy(last_ws);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (config->mouse_warping && warp) {
 | 
				
			||||||
			struct sway_container *last_output = last_focus;
 | 
								struct sway_container *last_output = last_focus;
 | 
				
			||||||
			if (last_output && last_output->type != C_OUTPUT) {
 | 
								if (last_output && last_output->type != C_OUTPUT) {
 | 
				
			||||||
				last_output = container_parent(last_output, C_OUTPUT);
 | 
									last_output = container_parent(last_output, C_OUTPUT);
 | 
				
			||||||
| 
						 | 
					@ -413,18 +414,22 @@ void seat_set_focus_warp(struct sway_seat *seat,
 | 
				
			||||||
			if (new_output && new_output->type != C_OUTPUT) {
 | 
								if (new_output && new_output->type != C_OUTPUT) {
 | 
				
			||||||
				new_output = container_parent(new_output, C_OUTPUT);
 | 
									new_output = container_parent(new_output, C_OUTPUT);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		if (new_output && last_output && new_output != last_output
 | 
								if (new_output && last_output && new_output != last_output) {
 | 
				
			||||||
				&& config->mouse_warping && warp) {
 | 
									double x = new_output->x + container->x +
 | 
				
			||||||
			struct wlr_output *output = new_output->sway_output->wlr_output;
 | 
										container->width / 2.0;
 | 
				
			||||||
			double x = container->x + output->lx + container->width / 2.0;
 | 
									double y = new_output->y + container->y +
 | 
				
			||||||
			double y = container->y + output->ly + container->height / 2.0;
 | 
										container->height / 2.0;
 | 
				
			||||||
 | 
									struct wlr_output *wlr_output =
 | 
				
			||||||
 | 
										new_output->sway_output->wlr_output;
 | 
				
			||||||
				if (!wlr_output_layout_contains_point(
 | 
									if (!wlr_output_layout_contains_point(
 | 
				
			||||||
						root_container.sway_root->output_layout,
 | 
											root_container.sway_root->output_layout,
 | 
				
			||||||
					output, seat->cursor->cursor->x, seat->cursor->cursor->y)) {
 | 
											wlr_output, seat->cursor->cursor->x,
 | 
				
			||||||
 | 
											seat->cursor->cursor->y)) {
 | 
				
			||||||
					wlr_cursor_warp(seat->cursor->cursor, NULL, x, y);
 | 
										wlr_cursor_warp(seat->cursor->cursor, NULL, x, y);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (last_focus && last_focus->type == C_VIEW &&
 | 
						if (last_focus && last_focus->type == C_VIEW &&
 | 
				
			||||||
			!input_manager_has_focus(seat->input, last_focus)) {
 | 
								!input_manager_has_focus(seat->input, last_focus)) {
 | 
				
			||||||
| 
						 | 
					@ -442,6 +447,29 @@ void seat_set_focus(struct sway_seat *seat,
 | 
				
			||||||
	seat_set_focus_warp(seat, container, true);
 | 
						seat_set_focus_warp(seat, container, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void seat_set_focus_surface(struct sway_seat *seat,
 | 
				
			||||||
 | 
							struct wlr_surface *surface) {
 | 
				
			||||||
 | 
						if (seat->focused_layer != NULL) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						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->has_focus = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						struct wlr_keyboard *keyboard =
 | 
				
			||||||
 | 
							wlr_seat_get_keyboard(seat->wlr_seat);
 | 
				
			||||||
 | 
						if (keyboard) {
 | 
				
			||||||
 | 
							wlr_seat_keyboard_notify_enter(seat->wlr_seat, surface,
 | 
				
			||||||
 | 
								keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							wlr_seat_keyboard_notify_enter(seat->wlr_seat, surface, NULL, 0, NULL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void seat_set_focus_layer(struct sway_seat *seat,
 | 
					void seat_set_focus_layer(struct sway_seat *seat,
 | 
				
			||||||
		struct wlr_layer_surface *layer) {
 | 
							struct wlr_layer_surface *layer) {
 | 
				
			||||||
	if (!layer && seat->focused_layer) {
 | 
						if (!layer && seat->focused_layer) {
 | 
				
			||||||
| 
						 | 
					@ -458,26 +486,10 @@ void seat_set_focus_layer(struct sway_seat *seat,
 | 
				
			||||||
	} else if (!layer || seat->focused_layer == layer) {
 | 
						} else if (!layer || seat->focused_layer == layer) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (seat->has_focus) {
 | 
						seat_set_focus_surface(seat, layer->surface);
 | 
				
			||||||
		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);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (layer->layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
 | 
						if (layer->layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
 | 
				
			||||||
		seat->focused_layer = layer;
 | 
							seat->focused_layer = layer;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	struct wlr_keyboard *keyboard =
 | 
					 | 
				
			||||||
		wlr_seat_get_keyboard(seat->wlr_seat);
 | 
					 | 
				
			||||||
	if (keyboard) {
 | 
					 | 
				
			||||||
		wlr_seat_keyboard_notify_enter(seat->wlr_seat,
 | 
					 | 
				
			||||||
				layer->surface, keyboard->keycodes,
 | 
					 | 
				
			||||||
				keyboard->num_keycodes, &keyboard->modifiers);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		wlr_seat_keyboard_notify_enter(seat->wlr_seat,
 | 
					 | 
				
			||||||
				layer->surface, NULL, 0, NULL);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void seat_set_exclusive_client(struct sway_seat *seat,
 | 
					void seat_set_exclusive_client(struct sway_seat *seat,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue