shell: Keep window 'activated' state if child has focus
Popups should have keyboard focus when active, but the toplevel window should still appear "active". Make sure this is the case by changing the "active" tracking to see whether any child surface has keyboard focus. Signed-off-by: Jonas Ådahl <jadahl@gmail.com>
This commit is contained in:
parent
28b3529ca8
commit
cc3d30c28b
|
@ -1386,18 +1386,75 @@ handle_pointer_focus(struct wl_listener *listener, void *data)
|
|||
weston_desktop_client_ping(client);
|
||||
}
|
||||
|
||||
static void
|
||||
has_keyboard_focused_child_callback(struct weston_desktop_surface *surface,
|
||||
void *user_data);
|
||||
|
||||
static void
|
||||
has_keyboard_focused_child_callback(struct weston_desktop_surface *surface,
|
||||
void *user_data)
|
||||
{
|
||||
struct weston_surface *es = weston_desktop_surface_get_surface(surface);
|
||||
struct shell_surface *shsurf = get_shell_surface(es);
|
||||
bool *has_keyboard_focus = user_data;
|
||||
|
||||
if (shsurf->focus_count > 0) {
|
||||
*has_keyboard_focus = true;
|
||||
return;
|
||||
}
|
||||
|
||||
weston_desktop_surface_foreach_child(shsurf->desktop_surface,
|
||||
has_keyboard_focused_child_callback,
|
||||
&has_keyboard_focus);
|
||||
}
|
||||
|
||||
static bool
|
||||
has_keyboard_focused_child(struct shell_surface *shsurf)
|
||||
{
|
||||
bool has_keyboard_focus = false;
|
||||
|
||||
if (shsurf->focus_count > 0)
|
||||
return true;
|
||||
|
||||
weston_desktop_surface_foreach_child(shsurf->desktop_surface,
|
||||
has_keyboard_focused_child_callback,
|
||||
&has_keyboard_focus);
|
||||
|
||||
return has_keyboard_focus;
|
||||
}
|
||||
|
||||
static void
|
||||
sync_surface_activated_state(struct shell_surface *shsurf)
|
||||
{
|
||||
struct weston_desktop_surface *surface = shsurf->desktop_surface;
|
||||
struct weston_desktop_surface *parent;
|
||||
struct weston_surface *parent_surface;
|
||||
|
||||
parent = weston_desktop_surface_get_parent(surface);
|
||||
if (parent) {
|
||||
parent_surface = weston_desktop_surface_get_surface(parent);
|
||||
sync_surface_activated_state(get_shell_surface(parent_surface));
|
||||
return;
|
||||
}
|
||||
|
||||
if (has_keyboard_focused_child(shsurf))
|
||||
weston_desktop_surface_set_activated(surface, true);
|
||||
else
|
||||
weston_desktop_surface_set_activated(surface, false);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_surface_deactivate(struct shell_surface *shsurf)
|
||||
{
|
||||
if (--shsurf->focus_count == 0)
|
||||
weston_desktop_surface_set_activated(shsurf->desktop_surface, false);
|
||||
sync_surface_activated_state(shsurf);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_surface_activate(struct shell_surface *shsurf)
|
||||
{
|
||||
if (shsurf->focus_count++ == 0)
|
||||
weston_desktop_surface_set_activated(shsurf->desktop_surface, true);
|
||||
sync_surface_activated_state(shsurf);
|
||||
}
|
||||
|
||||
/* The surface will be inserted into the list immediately after the link
|
||||
|
|
|
@ -216,6 +216,14 @@ struct weston_size
|
|||
weston_desktop_surface_get_max_size(struct weston_desktop_surface *surface);
|
||||
struct weston_size
|
||||
weston_desktop_surface_get_min_size(struct weston_desktop_surface *surface);
|
||||
struct weston_desktop_surface *
|
||||
weston_desktop_surface_get_parent(struct weston_desktop_surface *surface);
|
||||
void
|
||||
weston_desktop_surface_foreach_child(struct weston_desktop_surface *surface,
|
||||
void (* callback)(struct weston_desktop_surface *child,
|
||||
void *user_data),
|
||||
void *user_data);
|
||||
|
||||
|
||||
bool
|
||||
weston_desktop_window_menu_supported(struct weston_desktop *desktop);
|
||||
|
|
|
@ -195,8 +195,6 @@ const struct weston_desktop_surface_implementation *
|
|||
weston_desktop_surface_get_implementation(struct weston_desktop_surface *surface);
|
||||
void *
|
||||
weston_desktop_surface_get_implementation_data(struct weston_desktop_surface *surface);
|
||||
struct weston_desktop_surface *
|
||||
weston_desktop_surface_get_parent(struct weston_desktop_surface *surface);
|
||||
bool
|
||||
weston_desktop_surface_get_grab(struct weston_desktop_surface *surface);
|
||||
|
||||
|
|
|
@ -569,7 +569,7 @@ weston_desktop_surface_get_implementation_data(struct weston_desktop_surface *su
|
|||
return surface->implementation_data;
|
||||
}
|
||||
|
||||
struct weston_desktop_surface *
|
||||
WL_EXPORT struct weston_desktop_surface *
|
||||
weston_desktop_surface_get_parent(struct weston_desktop_surface *surface)
|
||||
{
|
||||
return surface->parent;
|
||||
|
@ -878,3 +878,15 @@ weston_desktop_surface_popup_dismiss(struct weston_desktop_surface *surface)
|
|||
wl_list_init(&surface->grab_link);
|
||||
weston_desktop_surface_close(surface);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_surface_foreach_child(struct weston_desktop_surface *surface,
|
||||
void (* callback)(struct weston_desktop_surface *child,
|
||||
void *user_data),
|
||||
void *user_data)
|
||||
{
|
||||
struct weston_desktop_surface *child;
|
||||
|
||||
wl_list_for_each(child, &surface->children_list, children_link)
|
||||
callback(child, user_data);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue