struct view_size_hints (*get_size_hints)(struct view *self);
/* if not implemented, VIEW_WANTS_FOCUS_ALWAYS is assumed */
enum view_wants_focus (*wants_focus)(struct view *self);
+ void (*offer_focus)(struct view *self);
/* returns true if view reserves space at screen edge */
bool (*has_strut_partial)(struct view *self);
/* returns true if view declared itself a window type */
*/
bool view_is_focusable(struct view *view);
+/*
+ * For use by desktop_focus_view() only - please do not call directly.
+ * See the description of VIEW_WANTS_FOCUS_OFFER for more information.
+ */
+void view_offer_focus(struct view *view);
+
void mappable_connect(struct mappable *mappable, struct wlr_surface *surface,
wl_notify_func_t notify_map, wl_notify_func_t notify_unmap);
void mappable_disconnect(struct mappable *mappable);
workspaces_switch_to(view->workspace, /*update_focus*/ false);
}
- /*
- * Give input focus, even if the view claims not to want it (see
- * view->impl->wants_focus). This is a workaround for so-called
- * "globally active" X11 views (MATLAB known to be one such)
- * that expect to be able to control focus themselves, but can't
- * under labwc since it's disallowed at the wlroots level.
- */
- struct seat *seat = &view->server->seat;
- if (view->surface != seat->seat->keyboard_state.focused_surface) {
- seat_focus_surface(seat, view->surface);
+ switch (view_wants_focus(view)) {
+ case VIEW_WANTS_FOCUS_ALWAYS:
+ ; /* works around "a label can only be part of a statement" */
+ struct seat *seat = &view->server->seat;
+ if (view->surface != seat->seat->keyboard_state.focused_surface) {
+ seat_focus_surface(seat, view->surface);
+ }
+ break;
+ case VIEW_WANTS_FOCUS_OFFER:
+ view_offer_focus(view);
+ break;
+ case VIEW_WANTS_FOCUS_NEVER:
+ break;
}
if (raise) {
* Globally Active client windows may receive a WM_TAKE_FOCUS
* message from the window manager. If they want the focus, they
* should respond with a SetInputFocus request.
- *
- * [Currently, labwc does not fully support clients voluntarily
- * taking focus via the WM_TAKE_FOCUS + SetInputFocus mechanism.
- * Instead, we try to guess whether the window wants focus based
- * on some heuristics -- see below.]
*/
case WLR_ICCCM_INPUT_MODEL_GLOBAL:
/*
return (bool)xsurface->strut_partial;
}
+static void
+xwayland_view_offer_focus(struct view *view)
+{
+ wlr_xwayland_surface_offer_focus(xwayland_surface_from_view(view));
+}
+
static struct wlr_xwayland_surface *
top_parent_of(struct view *view)
{
wl_list_remove(&xwayland_view->set_override_redirect.link);
wl_list_remove(&xwayland_view->set_strut_partial.link);
wl_list_remove(&xwayland_view->set_window_type.link);
+ wl_list_remove(&xwayland_view->focus_in.link);
wl_list_remove(&xwayland_view->map_request.link);
view_destroy(view);
}
}
+static void
+handle_focus_in(struct wl_listener *listener, void *data)
+{
+ struct xwayland_view *xwayland_view =
+ wl_container_of(listener, xwayland_view, focus_in);
+ struct view *view = &xwayland_view->base;
+ struct seat *seat = &view->server->seat;
+ if (view->surface != seat->seat->keyboard_state.focused_surface) {
+ seat_focus_surface(seat, view->surface);
+ }
+}
+
/*
* Sets the initial geometry of maximized/fullscreen views before
* actually mapping them, so that they can do their initial layout and
.append_children = xwayland_view_append_children,
.get_size_hints = xwayland_view_get_size_hints,
.wants_focus = xwayland_view_wants_focus,
+ .offer_focus = xwayland_view_offer_focus,
.has_strut_partial = xwayland_view_has_strut_partial,
.contains_window_type = xwayland_view_contains_window_type,
.get_pid = xwayland_view_get_pid,
CONNECT_SIGNAL(xsurface, xwayland_view, set_override_redirect);
CONNECT_SIGNAL(xsurface, xwayland_view, set_strut_partial);
CONNECT_SIGNAL(xsurface, xwayland_view, set_window_type);
+ CONNECT_SIGNAL(xsurface, xwayland_view, focus_in);
CONNECT_SIGNAL(xsurface, xwayland_view, map_request);
view_init(view);