patched foreign-toplevel-management

This commit is contained in:
2025-04-28 06:11:36 +02:00
parent 7f27da9ac4
commit 8313c7ed1b
2 changed files with 96 additions and 2 deletions

93
dwl.c
View File

@@ -24,6 +24,7 @@
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_drm.h>
#include <wlr/types/wlr_export_dmabuf_v1.h>
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
#include <wlr/types/wlr_fractional_scale_v1.h>
#include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
@@ -128,6 +129,11 @@ typedef struct {
struct wl_listener fullscreen;
struct wl_listener set_decoration_mode;
struct wl_listener destroy_decoration;
struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel;
struct wl_listener factivate;
struct wl_listener fclose;
struct wl_listener ffullscreen;
struct wl_listener fdestroy;
#ifdef XWAYLAND
struct wl_listener activate;
struct wl_listener associate;
@@ -351,6 +357,11 @@ static Monitor *xytomon(double x, double y);
static void xytonode(double x, double y, struct wlr_surface **psurface,
Client **pc, LayerSurface **pl, double *nx, double *ny);
static void zoom(const Arg *arg);
static void createforeigntoplevel(Client *c);
static void factivatenotify(struct wl_listener *listener, void *data);
static void fclosenotify(struct wl_listener *listener, void *data);
static void fdestroynotify(struct wl_listener *listener, void *data);
static void ffullscreennotify(struct wl_listener *listener, void *data);
/* variables */
static pid_t child_pid = -1;
@@ -395,6 +406,8 @@ static struct wlr_session_lock_manager_v1 *session_lock_mgr;
static struct wlr_scene_rect *locked_bg;
static struct wlr_session_lock_v1 *cur_lock;
static struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_mgr;
static struct wlr_seat *seat;
static KeyboardGroup *kb_group;
static unsigned int cursor_mode;
@@ -487,6 +500,11 @@ applyrules(Client *c)
appid = client_get_appid(c);
title = client_get_title(c);
if (c->foreign_toplevel) {
wlr_foreign_toplevel_handle_v1_set_app_id(c->foreign_toplevel, appid);
wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title);
}
for (r = rules; r < END(rules); r++) {
if ((!r->title || strstr(title, r->title))
&& (!r->id || strstr(appid, r->id))) {
@@ -1450,6 +1468,8 @@ focusclient(Client *c, int lift)
client_set_border_color(old_c, bordercolor);
client_activate_surface(old, 0);
if (old_c->foreign_toplevel)
wlr_foreign_toplevel_handle_v1_set_activated(old_c->foreign_toplevel, 0);
}
}
printstatus();
@@ -1468,6 +1488,8 @@ focusclient(Client *c, int lift)
/* Activate the new client */
client_activate_surface(client_surface(c), 1);
if (c->foreign_toplevel)
wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, 1);
}
void
@@ -1769,6 +1791,8 @@ mapnotify(struct wl_listener *listener, void *data)
c->border[i]->node.data = c;
}
createforeigntoplevel(c);
/* Initialize client geometry with room for border */
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
c->geom.width += 2 * c->bw;
@@ -2403,12 +2427,17 @@ setmon(Client *c, Monitor *m, uint32_t newtags)
c->prev = c->geom;
/* Scene graph sends surface leave/enter events on move and resize */
if (oldmon)
if (oldmon) {
if (c->foreign_toplevel)
wlr_foreign_toplevel_handle_v1_output_leave(c->foreign_toplevel, oldmon->wlr_output);
arrange(oldmon);
}
if (m) {
/* Make sure window actually overlaps with the monitor */
resize(c, c->geom, 0);
c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */
if (c->foreign_toplevel)
wlr_foreign_toplevel_handle_v1_output_enter(c->foreign_toplevel, m->wlr_output);
setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */
setfloating(c, c->isfloating);
}
@@ -2529,6 +2558,9 @@ setup(void)
power_mgr = wlr_output_power_manager_v1_create(dpy);
wl_signal_add(&power_mgr->events.set_mode, &output_power_mgr_set_mode);
/* Initializes foreign toplevel management */
foreign_toplevel_mgr = wlr_foreign_toplevel_manager_v1_create(dpy);
/* Creates an output layout, which a wlroots utility for working with an
* arrangement of screens in a physical layout. */
output_layout = wlr_output_layout_create(dpy);
@@ -2826,6 +2858,11 @@ unmapnotify(struct wl_listener *listener, void *data)
wl_list_remove(&c->flink);
}
if (c->foreign_toplevel) {
wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel);
c->foreign_toplevel = NULL;
}
wlr_scene_node_destroy(&c->scene->node);
printstatus();
motionnotify(0, NULL, 0, 0, 0, 0);
@@ -2941,6 +2978,12 @@ void
updatetitle(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, set_title);
if (c->foreign_toplevel) {
const char *title;
if (!(title = client_get_title(c)))
title = broken;
wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title);
}
if (c == focustop(c->mon))
printstatus();
}
@@ -3070,6 +3113,54 @@ zoom(const Arg *arg)
arrange(selmon);
}
void
createforeigntoplevel(Client *c)
{
c->foreign_toplevel = wlr_foreign_toplevel_handle_v1_create(foreign_toplevel_mgr);
LISTEN(&c->foreign_toplevel->events.request_activate, &c->factivate, factivatenotify);
LISTEN(&c->foreign_toplevel->events.request_close, &c->fclose, fclosenotify);
LISTEN(&c->foreign_toplevel->events.request_fullscreen, &c->ffullscreen, ffullscreennotify);
LISTEN(&c->foreign_toplevel->events.destroy, &c->fdestroy, fdestroynotify);
}
void
factivatenotify(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, factivate);
if (c->mon == selmon) {
c->tags = c->mon->tagset[c->mon->seltags];
} else {
setmon(c, selmon, 0);
}
focusclient(c, 1);
arrange(c->mon);
}
void
fclosenotify(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, fclose);
client_send_close(c);
}
void
ffullscreennotify(struct wl_listener *listener, void *data) {
Client *c = wl_container_of(listener, c, ffullscreen);
struct wlr_foreign_toplevel_handle_v1_fullscreen_event *event = data;
setfullscreen(c, event->fullscreen);
}
void
fdestroynotify(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, fdestroy);
wl_list_remove(&c->factivate.link);
wl_list_remove(&c->fclose.link);
wl_list_remove(&c->ffullscreen.link);
wl_list_remove(&c->fdestroy.link);
}
#ifdef XWAYLAND
void
activatex11(struct wl_listener *listener, void *data)