mirror of
https://github.com/labwc/labwc.git
synced 2026-02-24 01:40:15 -05:00
xwayland: better support for keyboard focus grabs
Use the new grab_focus signal as a more reliable way to tell when an unmanaged (override-redirect) surface wants focus.
This commit is contained in:
parent
c00baa1651
commit
423cb6923f
2 changed files with 29 additions and 3 deletions
|
|
@ -47,12 +47,20 @@ struct xwayland_unmanaged {
|
||||||
|
|
||||||
struct wl_listener associate;
|
struct wl_listener associate;
|
||||||
struct wl_listener dissociate;
|
struct wl_listener dissociate;
|
||||||
|
struct wl_listener grab_focus;
|
||||||
struct wl_listener request_activate;
|
struct wl_listener request_activate;
|
||||||
struct wl_listener request_configure;
|
struct wl_listener request_configure;
|
||||||
/* struct wl_listener request_fullscreen; */
|
/* struct wl_listener request_fullscreen; */
|
||||||
struct wl_listener set_geometry;
|
struct wl_listener set_geometry;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wl_listener set_override_redirect;
|
struct wl_listener set_override_redirect;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* True if the surface has performed a keyboard grab. labwc
|
||||||
|
* honors keyboard grabs and will give the surface focus when
|
||||||
|
* it's mapped (which may occur slightly later) and on top.
|
||||||
|
*/
|
||||||
|
bool ever_grabbed_focus;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xwayland_view {
|
struct xwayland_view {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,20 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "xwayland.h"
|
#include "xwayland.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_grab_focus(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct xwayland_unmanaged *unmanaged =
|
||||||
|
wl_container_of(listener, unmanaged, grab_focus);
|
||||||
|
|
||||||
|
unmanaged->ever_grabbed_focus = true;
|
||||||
|
if (unmanaged->node) {
|
||||||
|
assert(unmanaged->xwayland_surface->surface);
|
||||||
|
seat_focus_surface(&unmanaged->server->seat,
|
||||||
|
unmanaged->xwayland_surface->surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_request_configure(struct wl_listener *listener, void *data)
|
handle_request_configure(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
|
@ -46,7 +60,8 @@ handle_map(struct wl_listener *listener, void *data)
|
||||||
|
|
||||||
CONNECT_SIGNAL(xsurface, unmanaged, set_geometry);
|
CONNECT_SIGNAL(xsurface, unmanaged, set_geometry);
|
||||||
|
|
||||||
if (wlr_xwayland_surface_override_redirect_wants_focus(xsurface)) {
|
if (wlr_xwayland_surface_override_redirect_wants_focus(xsurface)
|
||||||
|
|| unmanaged->ever_grabbed_focus) {
|
||||||
seat_focus_surface(&unmanaged->server->seat, xsurface->surface);
|
seat_focus_surface(&unmanaged->server->seat, xsurface->surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,7 +81,8 @@ focus_next_surface(struct server *server, struct wlr_xwayland_surface *xsurface)
|
||||||
struct wl_list *list = &server->unmanaged_surfaces;
|
struct wl_list *list = &server->unmanaged_surfaces;
|
||||||
wl_list_for_each_reverse(u, list, link) {
|
wl_list_for_each_reverse(u, list, link) {
|
||||||
struct wlr_xwayland_surface *prev = u->xwayland_surface;
|
struct wlr_xwayland_surface *prev = u->xwayland_surface;
|
||||||
if (wlr_xwayland_surface_override_redirect_wants_focus(prev)) {
|
if (wlr_xwayland_surface_override_redirect_wants_focus(prev)
|
||||||
|
|| u->ever_grabbed_focus) {
|
||||||
seat_focus_surface(&server->seat, prev->surface);
|
seat_focus_surface(&server->seat, prev->surface);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -152,9 +168,10 @@ handle_destroy(struct wl_listener *listener, void *data)
|
||||||
|
|
||||||
wl_list_remove(&unmanaged->associate.link);
|
wl_list_remove(&unmanaged->associate.link);
|
||||||
wl_list_remove(&unmanaged->dissociate.link);
|
wl_list_remove(&unmanaged->dissociate.link);
|
||||||
|
wl_list_remove(&unmanaged->grab_focus.link);
|
||||||
|
wl_list_remove(&unmanaged->request_activate.link);
|
||||||
wl_list_remove(&unmanaged->request_configure.link);
|
wl_list_remove(&unmanaged->request_configure.link);
|
||||||
wl_list_remove(&unmanaged->set_override_redirect.link);
|
wl_list_remove(&unmanaged->set_override_redirect.link);
|
||||||
wl_list_remove(&unmanaged->request_activate.link);
|
|
||||||
wl_list_remove(&unmanaged->destroy.link);
|
wl_list_remove(&unmanaged->destroy.link);
|
||||||
free(unmanaged);
|
free(unmanaged);
|
||||||
}
|
}
|
||||||
|
|
@ -223,6 +240,7 @@ xwayland_unmanaged_create(struct server *server,
|
||||||
CONNECT_SIGNAL(xsurface, unmanaged, associate);
|
CONNECT_SIGNAL(xsurface, unmanaged, associate);
|
||||||
CONNECT_SIGNAL(xsurface, unmanaged, dissociate);
|
CONNECT_SIGNAL(xsurface, unmanaged, dissociate);
|
||||||
CONNECT_SIGNAL(xsurface, unmanaged, destroy);
|
CONNECT_SIGNAL(xsurface, unmanaged, destroy);
|
||||||
|
CONNECT_SIGNAL(xsurface, unmanaged, grab_focus);
|
||||||
CONNECT_SIGNAL(xsurface, unmanaged, request_activate);
|
CONNECT_SIGNAL(xsurface, unmanaged, request_activate);
|
||||||
CONNECT_SIGNAL(xsurface, unmanaged, request_configure);
|
CONNECT_SIGNAL(xsurface, unmanaged, request_configure);
|
||||||
CONNECT_SIGNAL(xsurface, unmanaged, set_override_redirect);
|
CONNECT_SIGNAL(xsurface, unmanaged, set_override_redirect);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue