2021-09-24 21:45:48 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2022-10-27 13:53:50 -04:00
|
|
|
#include <assert.h>
|
2025-07-28 01:22:10 -04:00
|
|
|
#include <wlr/types/wlr_compositor.h>
|
|
|
|
|
#include <wlr/types/wlr_scene.h>
|
|
|
|
|
#include <wlr/types/wlr_seat.h>
|
2023-01-07 17:50:33 -05:00
|
|
|
#include <wlr/xwayland.h>
|
2022-10-05 08:43:56 +02:00
|
|
|
#include "common/list.h"
|
2023-10-16 02:01:35 -04:00
|
|
|
#include "common/macros.h"
|
2022-09-16 18:41:02 -04:00
|
|
|
#include "common/mem.h"
|
2020-09-04 20:25:20 +01:00
|
|
|
#include "labwc.h"
|
2023-01-07 17:50:33 -05:00
|
|
|
#include "xwayland.h"
|
2020-09-04 20:25:20 +01:00
|
|
|
|
2024-02-13 22:25:20 -05:00
|
|
|
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);
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
seat_focus_surface(&g_server.seat,
|
2024-02-13 22:25:20 -05:00
|
|
|
unmanaged->xwayland_surface->surface);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
static void
|
2023-10-16 02:01:35 -04:00
|
|
|
handle_request_configure(struct wl_listener *listener, void *data)
|
2020-09-04 20:25:20 +01:00
|
|
|
{
|
|
|
|
|
struct xwayland_unmanaged *unmanaged =
|
|
|
|
|
wl_container_of(listener, unmanaged, request_configure);
|
|
|
|
|
struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface;
|
|
|
|
|
struct wlr_xwayland_surface_configure_event *ev = data;
|
2022-08-10 06:14:55 +02:00
|
|
|
wlr_xwayland_surface_configure(xsurface, ev->x, ev->y, ev->width, ev->height);
|
|
|
|
|
if (unmanaged->node) {
|
|
|
|
|
wlr_scene_node_set_position(unmanaged->node, ev->x, ev->y);
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
cursor_update_focus();
|
2022-08-10 06:14:55 +02:00
|
|
|
}
|
2020-09-04 20:25:20 +01:00
|
|
|
}
|
|
|
|
|
|
2022-06-04 13:20:40 +01:00
|
|
|
static void
|
2023-10-16 02:01:35 -04:00
|
|
|
handle_set_geometry(struct wl_listener *listener, void *data)
|
2022-06-04 13:20:40 +01:00
|
|
|
{
|
|
|
|
|
struct xwayland_unmanaged *unmanaged =
|
2022-06-05 20:42:02 +00:00
|
|
|
wl_container_of(listener, unmanaged, set_geometry);
|
2022-06-04 13:20:40 +01:00
|
|
|
struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface;
|
2022-08-10 06:14:55 +02:00
|
|
|
if (unmanaged->node) {
|
|
|
|
|
wlr_scene_node_set_position(unmanaged->node, xsurface->x, xsurface->y);
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
cursor_update_focus();
|
2022-08-10 06:14:55 +02:00
|
|
|
}
|
2022-06-04 13:20:40 +01:00
|
|
|
}
|
|
|
|
|
|
2023-01-07 17:50:33 -05:00
|
|
|
static void
|
2023-10-16 02:01:35 -04:00
|
|
|
handle_map(struct wl_listener *listener, void *data)
|
2020-09-04 20:25:20 +01:00
|
|
|
{
|
|
|
|
|
struct xwayland_unmanaged *unmanaged =
|
2023-06-15 02:35:43 -07:00
|
|
|
wl_container_of(listener, unmanaged, mappable.map);
|
2020-09-04 20:25:20 +01:00
|
|
|
struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface;
|
2022-10-27 13:53:50 -04:00
|
|
|
assert(!unmanaged->node);
|
2020-09-04 20:25:20 +01:00
|
|
|
|
2022-09-01 14:33:42 -04:00
|
|
|
/* Stack new surface on top */
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
wl_list_append(&g_server.unmanaged_surfaces, &unmanaged->link);
|
2020-09-04 20:25:20 +01:00
|
|
|
|
2023-10-16 02:01:35 -04:00
|
|
|
CONNECT_SIGNAL(xsurface, unmanaged, set_geometry);
|
2022-06-04 13:20:40 +01:00
|
|
|
|
2024-02-13 22:25:20 -05:00
|
|
|
if (wlr_xwayland_surface_override_redirect_wants_focus(xsurface)
|
|
|
|
|
|| unmanaged->ever_grabbed_focus) {
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
seat_focus_surface(&g_server.seat, xsurface->surface);
|
2020-09-28 20:41:41 +01:00
|
|
|
}
|
2022-02-11 23:12:45 +00:00
|
|
|
|
2026-02-23 16:34:36 -05:00
|
|
|
struct wlr_scene_surface *scene_surface = wlr_scene_surface_create(
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
g_server.unmanaged_tree, xsurface->surface);
|
2026-02-23 16:34:36 -05:00
|
|
|
die_if_null(scene_surface);
|
|
|
|
|
unmanaged->node = &scene_surface->buffer->node;
|
|
|
|
|
|
2022-07-23 11:20:34 -04:00
|
|
|
wlr_scene_node_set_position(unmanaged->node, xsurface->x, xsurface->y);
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
cursor_update_focus();
|
2020-09-04 20:25:20 +01:00
|
|
|
}
|
|
|
|
|
|
2022-09-03 13:10:33 -04:00
|
|
|
static void
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
focus_next_surface(struct wlr_xwayland_surface *xsurface)
|
2022-09-03 13:10:33 -04:00
|
|
|
{
|
|
|
|
|
/* Try to focus on last created unmanaged xwayland surface */
|
|
|
|
|
struct xwayland_unmanaged *u;
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
struct wl_list *list = &g_server.unmanaged_surfaces;
|
2022-11-03 19:58:21 +00:00
|
|
|
wl_list_for_each_reverse(u, list, link) {
|
2022-09-03 13:10:33 -04:00
|
|
|
struct wlr_xwayland_surface *prev = u->xwayland_surface;
|
2024-02-13 22:25:20 -05:00
|
|
|
if (wlr_xwayland_surface_override_redirect_wants_focus(prev)
|
|
|
|
|
|| u->ever_grabbed_focus) {
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
seat_focus_surface(&g_server.seat, prev->surface);
|
2022-09-03 13:10:33 -04:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2025-06-11 15:40:37 -04:00
|
|
|
* Unmanaged surfaces do not clear the active view when mapped.
|
|
|
|
|
* Therefore, we can simply give the focus back to the active
|
|
|
|
|
* view when the last unmanaged surface is unmapped.
|
|
|
|
|
*
|
|
|
|
|
* Also note that resetting the focus here is only on the
|
|
|
|
|
* compositor side. On the xwayland server side, focus is never
|
|
|
|
|
* given to unmanaged surfaces to begin with - keyboard grabs
|
|
|
|
|
* are used instead.
|
|
|
|
|
*
|
|
|
|
|
* In the case of Globally Active input windows, calling
|
|
|
|
|
* view_offer_focus() at this point is both unnecessary and
|
|
|
|
|
* insufficient, since it doesn't update the seat focus
|
|
|
|
|
* immediately and ultimately results in a loss of focus.
|
|
|
|
|
*
|
|
|
|
|
* For the above reasons, we avoid calling desktop_focus_view()
|
|
|
|
|
* here and instead call seat_focus_surface() directly.
|
|
|
|
|
*
|
|
|
|
|
* If modifying this logic, please test for regressions with
|
|
|
|
|
* menus/tooltips in JetBrains CLion or similar.
|
2022-09-03 13:10:33 -04:00
|
|
|
*/
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
if (g_server.active_view) {
|
|
|
|
|
seat_focus_surface(&g_server.seat, g_server.active_view->surface);
|
2025-06-11 15:40:37 -04:00
|
|
|
}
|
2022-09-03 13:10:33 -04:00
|
|
|
}
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
static void
|
2023-10-16 02:01:35 -04:00
|
|
|
handle_unmap(struct wl_listener *listener, void *data)
|
2020-09-04 20:25:20 +01:00
|
|
|
{
|
|
|
|
|
struct xwayland_unmanaged *unmanaged =
|
2023-06-15 02:35:43 -07:00
|
|
|
wl_container_of(listener, unmanaged, mappable.unmap);
|
2020-09-04 20:25:20 +01:00
|
|
|
struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface;
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
struct seat *seat = &g_server.seat;
|
2022-10-27 13:53:50 -04:00
|
|
|
assert(unmanaged->node);
|
2022-09-01 17:50:28 -04:00
|
|
|
|
2020-09-04 20:25:20 +01:00
|
|
|
wl_list_remove(&unmanaged->link);
|
2022-06-04 13:20:40 +01:00
|
|
|
wl_list_remove(&unmanaged->set_geometry.link);
|
2020-09-04 20:25:20 +01:00
|
|
|
|
2022-08-10 06:14:55 +02:00
|
|
|
/*
|
2025-11-24 11:27:19 -05:00
|
|
|
* Destroy the scene node. It would get destroyed later when
|
|
|
|
|
* the wlr_surface is destroyed, but if the unmanaged surface
|
|
|
|
|
* gets converted to a managed surface, that may be a while.
|
2022-08-10 06:14:55 +02:00
|
|
|
*/
|
2025-11-24 11:27:19 -05:00
|
|
|
wlr_scene_node_destroy(unmanaged->node);
|
2022-08-10 06:14:55 +02:00
|
|
|
unmanaged->node = NULL;
|
2025-11-24 11:27:19 -05:00
|
|
|
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
cursor_update_focus();
|
2022-08-10 06:14:55 +02:00
|
|
|
|
2020-10-08 20:22:52 +01:00
|
|
|
if (seat->seat->keyboard_state.focused_surface == xsurface->surface) {
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
focus_next_surface(xsurface);
|
2020-09-04 20:25:20 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-15 02:35:43 -07:00
|
|
|
static void
|
|
|
|
|
handle_associate(struct wl_listener *listener, void *data)
|
|
|
|
|
{
|
|
|
|
|
struct xwayland_unmanaged *unmanaged =
|
|
|
|
|
wl_container_of(listener, unmanaged, associate);
|
|
|
|
|
assert(unmanaged->xwayland_surface &&
|
|
|
|
|
unmanaged->xwayland_surface->surface);
|
|
|
|
|
|
|
|
|
|
mappable_connect(&unmanaged->mappable,
|
|
|
|
|
unmanaged->xwayland_surface->surface,
|
|
|
|
|
handle_map, handle_unmap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
handle_dissociate(struct wl_listener *listener, void *data)
|
|
|
|
|
{
|
|
|
|
|
struct xwayland_unmanaged *unmanaged =
|
|
|
|
|
wl_container_of(listener, unmanaged, dissociate);
|
|
|
|
|
|
|
|
|
|
mappable_disconnect(&unmanaged->mappable);
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
static void
|
2023-10-16 02:01:35 -04:00
|
|
|
handle_destroy(struct wl_listener *listener, void *data)
|
2020-09-04 20:25:20 +01:00
|
|
|
{
|
|
|
|
|
struct xwayland_unmanaged *unmanaged =
|
|
|
|
|
wl_container_of(listener, unmanaged, destroy);
|
2023-06-15 02:35:43 -07:00
|
|
|
|
|
|
|
|
if (unmanaged->mappable.connected) {
|
|
|
|
|
mappable_disconnect(&unmanaged->mappable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wl_list_remove(&unmanaged->associate.link);
|
|
|
|
|
wl_list_remove(&unmanaged->dissociate.link);
|
2024-02-13 22:25:20 -05:00
|
|
|
wl_list_remove(&unmanaged->grab_focus.link);
|
|
|
|
|
wl_list_remove(&unmanaged->request_activate.link);
|
2022-06-05 22:10:15 +01:00
|
|
|
wl_list_remove(&unmanaged->request_configure.link);
|
2023-10-16 02:01:35 -04:00
|
|
|
wl_list_remove(&unmanaged->set_override_redirect.link);
|
2020-09-04 20:25:20 +01:00
|
|
|
wl_list_remove(&unmanaged->destroy.link);
|
|
|
|
|
free(unmanaged);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-04 13:20:40 +01:00
|
|
|
static void
|
2023-10-16 02:01:35 -04:00
|
|
|
handle_set_override_redirect(struct wl_listener *listener, void *data)
|
2022-06-04 13:20:40 +01:00
|
|
|
{
|
2023-04-17 17:05:13 +01:00
|
|
|
wlr_log(WLR_DEBUG, "handle unmanaged override_redirect");
|
|
|
|
|
struct xwayland_unmanaged *unmanaged =
|
2023-10-16 02:01:35 -04:00
|
|
|
wl_container_of(listener, unmanaged, set_override_redirect);
|
2023-04-17 17:05:13 +01:00
|
|
|
struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface;
|
|
|
|
|
|
2023-06-15 02:35:43 -07:00
|
|
|
bool mapped = xsurface->surface && xsurface->surface->mapped;
|
2023-04-17 17:05:13 +01:00
|
|
|
if (mapped) {
|
2023-06-15 02:35:43 -07:00
|
|
|
handle_unmap(&unmanaged->mappable.unmap, NULL);
|
2023-04-17 17:05:13 +01:00
|
|
|
}
|
2023-10-16 02:01:35 -04:00
|
|
|
handle_destroy(&unmanaged->destroy, NULL);
|
2023-04-17 17:05:13 +01:00
|
|
|
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
xwayland_view_create(xsurface, mapped);
|
2022-06-04 13:20:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2023-10-16 02:01:35 -04:00
|
|
|
handle_request_activate(struct wl_listener *listener, void *data)
|
2022-06-04 13:20:40 +01:00
|
|
|
{
|
2023-04-19 10:14:51 +01:00
|
|
|
wlr_log(WLR_DEBUG, "handle unmanaged request_activate");
|
2023-09-29 04:50:47 +02:00
|
|
|
struct xwayland_unmanaged *unmanaged =
|
|
|
|
|
wl_container_of(listener, unmanaged, request_activate);
|
|
|
|
|
struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface;
|
2023-06-15 02:35:43 -07:00
|
|
|
if (!xsurface->surface || !xsurface->surface->mapped) {
|
2023-04-19 10:14:51 +01:00
|
|
|
return;
|
|
|
|
|
}
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
struct seat *seat = &g_server.seat;
|
2023-04-19 20:40:40 +01:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Validate that the unmanaged surface trying to grab focus is actually
|
2025-06-11 15:40:37 -04:00
|
|
|
* a child of the active view before granting the request.
|
|
|
|
|
*
|
|
|
|
|
* FIXME: this logic is a bit incomplete/inconsistent. Refer to
|
|
|
|
|
* https://github.com/labwc/labwc/discussions/2821 for more info.
|
2023-04-19 20:40:40 +01:00
|
|
|
*/
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
struct view *view = g_server.active_view;
|
2023-04-19 20:40:40 +01:00
|
|
|
if (view && view->type == LAB_XWAYLAND_VIEW) {
|
|
|
|
|
struct wlr_xwayland_surface *surf =
|
2023-02-03 14:53:26 -05:00
|
|
|
wlr_xwayland_surface_try_from_wlr_surface(view->surface);
|
2023-04-19 20:40:40 +01:00
|
|
|
if (surf && surf->pid != xsurface->pid) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-19 10:14:51 +01:00
|
|
|
seat_focus_surface(seat, xsurface->surface);
|
2022-06-04 13:20:40 +01:00
|
|
|
}
|
|
|
|
|
|
2023-01-07 17:50:33 -05:00
|
|
|
void
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
xwayland_unmanaged_create(struct wlr_xwayland_surface *xsurface, bool mapped)
|
2020-09-04 20:25:20 +01:00
|
|
|
{
|
2022-09-18 15:22:26 -04:00
|
|
|
struct xwayland_unmanaged *unmanaged = znew(*unmanaged);
|
2020-09-04 20:25:20 +01:00
|
|
|
unmanaged->xwayland_surface = xsurface;
|
2023-09-30 01:31:37 -04:00
|
|
|
/*
|
|
|
|
|
* xsurface->data is presumed to be a (struct view *) if set,
|
|
|
|
|
* so it must be left NULL for an unmanaged surface (it should
|
|
|
|
|
* be NULL already at this point).
|
|
|
|
|
*/
|
|
|
|
|
assert(!xsurface->data);
|
2022-06-05 22:10:15 +01:00
|
|
|
|
2023-06-15 02:35:43 -07:00
|
|
|
CONNECT_SIGNAL(xsurface, unmanaged, associate);
|
|
|
|
|
CONNECT_SIGNAL(xsurface, unmanaged, dissociate);
|
2023-10-16 02:01:35 -04:00
|
|
|
CONNECT_SIGNAL(xsurface, unmanaged, destroy);
|
2024-02-13 22:25:20 -05:00
|
|
|
CONNECT_SIGNAL(xsurface, unmanaged, grab_focus);
|
2023-10-16 02:01:35 -04:00
|
|
|
CONNECT_SIGNAL(xsurface, unmanaged, request_activate);
|
|
|
|
|
CONNECT_SIGNAL(xsurface, unmanaged, request_configure);
|
|
|
|
|
CONNECT_SIGNAL(xsurface, unmanaged, set_override_redirect);
|
2022-06-04 13:20:40 +01:00
|
|
|
|
2024-01-23 18:22:56 -05:00
|
|
|
if (xsurface->surface) {
|
|
|
|
|
handle_associate(&unmanaged->associate, NULL);
|
|
|
|
|
}
|
2023-01-07 17:50:33 -05:00
|
|
|
if (mapped) {
|
2023-06-15 02:35:43 -07:00
|
|
|
handle_map(&unmanaged->mappable.map, NULL);
|
2023-01-07 17:50:33 -05:00
|
|
|
}
|
2020-09-04 20:25:20 +01:00
|
|
|
}
|