wl_container_of(listener, xwayland_view, focus_in);
struct view *view = &xwayland_view->base;
struct seat *seat = &view->server->seat;
+
+ if (!view->surface) {
+ /*
+ * It is rare but possible for the focus_in event to be
+ * received before the map event. This has been seen
+ * during CLion startup, when focus is initially offered
+ * to the splash screen but accepted later by the main
+ * window instead. (In this case, the focus transfer is
+ * client-initiated but allowed by wlroots because the
+ * same PID owns both windows.)
+ *
+ * Set a flag to record this condition, and update the
+ * seat focus later when the view is actually mapped.
+ */
+ wlr_log(WLR_DEBUG, "focus_in received before map");
+ xwayland_view->focused_before_map = true;
+ return;
+ }
+
if (view->surface != seat->seat->keyboard_state.focused_surface) {
seat_focus_surface(seat, view->surface);
}
wl_signal_add(&xwayland_surface->surface->events.commit, &view->commit);
view->commit.notify = handle_commit;
+ /*
+ * If the view was focused (on the xwayland server side) before
+ * being mapped, update the seat focus now. Note that this only
+ * really matters in the case of Globally Active input windows.
+ * In all other cases, it's redundant since view_impl_map()
+ * results in the view being focused anyway.
+ */
+ if (xwayland_view->focused_before_map) {
+ xwayland_view->focused_before_map = false;
+ seat_focus_surface(&view->server->seat, view->surface);
+ }
+
view_impl_map(view);
view->been_mapped = true;