mirror of
https://github.com/labwc/labwc.git
synced 2025-11-02 09:01:47 -05:00
cursor: allow re-focusing xwayland-unmanaged surfaces
We already allow some xwayland-unmanaged surfaces to take focus on map, if indicated by wlr_xwayland_or_surface_wants_focus(). But once these surfaces lose focus, they never regain it again. Add desktop_focus_view_or_surface() and call it in the appropriate places to allow these views to regain focus in the usual ways (e.g. clicking on them or focus-follows-mouse).
This commit is contained in:
parent
7aa1dc1ca5
commit
c5437b1153
3 changed files with 47 additions and 5 deletions
|
|
@ -382,6 +382,14 @@ void foreign_toplevel_update_outputs(struct view *view);
|
||||||
* session is locked/input is inhibited; it will simply do nothing.
|
* session is locked/input is inhibited; it will simply do nothing.
|
||||||
*/
|
*/
|
||||||
void desktop_focus_view(struct view *view, bool raise);
|
void desktop_focus_view(struct view *view, bool raise);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* desktop_focus_view_or_surface() - like desktop_focus_view() but can
|
||||||
|
* also focus other (e.g. xwayland-unmanaged) surfaces
|
||||||
|
*/
|
||||||
|
void desktop_focus_view_or_surface(struct seat *seat, struct view *view,
|
||||||
|
struct wlr_surface *surface, bool raise);
|
||||||
|
|
||||||
void desktop_arrange_all_views(struct server *server);
|
void desktop_arrange_all_views(struct server *server);
|
||||||
void desktop_focus_output(struct output *output);
|
void desktop_focus_output(struct output *output);
|
||||||
struct view *desktop_topmost_focusable_view(struct server *server);
|
struct view *desktop_topmost_focusable_view(struct server *server);
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@
|
||||||
#include "workspaces.h"
|
#include "workspaces.h"
|
||||||
#include "xwayland.h"
|
#include "xwayland.h"
|
||||||
|
|
||||||
|
#if HAVE_XWAYLAND
|
||||||
|
#include <wlr/xwayland.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
desktop_arrange_all_views(struct server *server)
|
desktop_arrange_all_views(struct server *server)
|
||||||
{
|
{
|
||||||
|
|
@ -84,6 +88,25 @@ desktop_focus_view(struct view *view, bool raise)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: focus layer-shell surfaces also? */
|
||||||
|
void
|
||||||
|
desktop_focus_view_or_surface(struct seat *seat, struct view *view,
|
||||||
|
struct wlr_surface *surface, bool raise)
|
||||||
|
{
|
||||||
|
assert(view || surface);
|
||||||
|
if (view) {
|
||||||
|
desktop_focus_view(view, raise);
|
||||||
|
#if HAVE_XWAYLAND
|
||||||
|
} else if (wlr_surface_is_xwayland_surface(surface)) {
|
||||||
|
struct wlr_xwayland_surface *xsurface =
|
||||||
|
wlr_xwayland_surface_from_wlr_surface(surface);
|
||||||
|
if (xsurface && wlr_xwayland_or_surface_wants_focus(xsurface)) {
|
||||||
|
seat_focus_surface(seat, surface);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct wl_list *
|
static struct wl_list *
|
||||||
get_prev_item(struct wl_list *item)
|
get_prev_item(struct wl_list *item)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -479,8 +479,9 @@ process_cursor_motion(struct server *server, uint32_t time)
|
||||||
dnd_icons_move(seat, seat->cursor->x, seat->cursor->y);
|
dnd_icons_move(seat, seat->cursor->x, seat->cursor->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.view && rc.focus_follow_mouse) {
|
if ((ctx.view || ctx.surface) && rc.focus_follow_mouse) {
|
||||||
desktop_focus_view(ctx.view, rc.raise_on_focus);
|
desktop_focus_view_or_surface(seat, ctx.view, ctx.surface,
|
||||||
|
rc.raise_on_focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mousebind *mousebind;
|
struct mousebind *mousebind;
|
||||||
|
|
@ -517,11 +518,12 @@ _cursor_update_focus(struct server *server)
|
||||||
/* Focus surface under cursor if it isn't already focused */
|
/* Focus surface under cursor if it isn't already focused */
|
||||||
struct cursor_context ctx = get_cursor_context(server);
|
struct cursor_context ctx = get_cursor_context(server);
|
||||||
|
|
||||||
if (ctx.view && rc.focus_follow_mouse
|
if ((ctx.view || ctx.surface) && rc.focus_follow_mouse
|
||||||
&& !rc.focus_follow_mouse_requires_movement
|
&& !rc.focus_follow_mouse_requires_movement
|
||||||
&& !server->osd_state.cycle_view) {
|
&& !server->osd_state.cycle_view) {
|
||||||
/* Prevents changing keyboard focus during A-Tab */
|
/* Prevents changing keyboard focus during A-Tab */
|
||||||
desktop_focus_view(ctx.view, rc.raise_on_focus);
|
desktop_focus_view_or_surface(&server->seat, ctx.view,
|
||||||
|
ctx.surface, rc.raise_on_focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor_update_common(server, &ctx, msec(&now),
|
cursor_update_common(server, &ctx, msec(&now),
|
||||||
|
|
@ -908,13 +910,22 @@ cursor_button_press(struct seat *seat, struct wlr_pointer_button_event *event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle _press_ on a layer surface */
|
/*
|
||||||
|
* On press, set focus to a non-view surface that wants it.
|
||||||
|
* Action processing does not run for these surfaces and thus
|
||||||
|
* the Focus action (used for normal views) does not work.
|
||||||
|
*/
|
||||||
if (ctx.type == LAB_SSD_LAYER_SURFACE) {
|
if (ctx.type == LAB_SSD_LAYER_SURFACE) {
|
||||||
struct wlr_layer_surface_v1 *layer =
|
struct wlr_layer_surface_v1 *layer =
|
||||||
wlr_layer_surface_v1_from_wlr_surface(ctx.surface);
|
wlr_layer_surface_v1_from_wlr_surface(ctx.surface);
|
||||||
if (layer && layer->current.keyboard_interactive) {
|
if (layer && layer->current.keyboard_interactive) {
|
||||||
seat_set_focus_layer(seat, layer);
|
seat_set_focus_layer(seat, layer);
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_XWAYLAND
|
||||||
|
} else if (ctx.type == LAB_SSD_UNMANAGED) {
|
||||||
|
desktop_focus_view_or_surface(seat, NULL, ctx.surface,
|
||||||
|
/*raise*/ false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue