foreign-toplevel: simplify and fully separate ext-foreign/wlr-foreign

Currently, the dependencies between foreign-toplevel[-internal],
ext-foreign, and wlr-foreign are cyclical and a bit complex.

I suggest we reorganize it into a simpler hierarchy:

  foreign-toplevel/
    -> foreign.c/h
      -> (depends on) ext-foreign.c/h
      -> (depends on) wlr-foreign.c/h

The refactored code is smaller and (IMO) easier to follow.

In detail:

- Add include/foreign-toplevel folder mirroring src/foreign-toplevel
- Split foreign-toplevel-internal.h to ext-foreign.h and wlr-foreign.h
- Eliminate ext-/wlr-foreign.c -> foreign.c reverse dependencies
  (including internal signals and foreign_request* functions)
- Make struct foreign_toplevel private to foreign.c

Lightly tested with qmpanel (which uses wlr-foreign-toplevel).

v2: reorder foreign-toplevel internal API funcs
This commit is contained in:
John Lindgren 2025-08-07 20:30:59 -04:00
parent 55b495f398
commit 02df0a15d7
11 changed files with 202 additions and 271 deletions

View file

@ -1,83 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_FOREIGN_TOPLEVEL_INTERNAL_H
#define LABWC_FOREIGN_TOPLEVEL_INTERNAL_H
#include <stdbool.h>
#include <wayland-server-core.h>
#include "foreign-toplevel.h"
struct foreign_toplevel {
struct view *view;
/* *-toplevel implementations */
struct wlr_foreign_toplevel {
struct wlr_foreign_toplevel_handle_v1 *handle;
/* Client side events */
struct {
struct wl_listener request_maximize;
struct wl_listener request_minimize;
struct wl_listener request_fullscreen;
struct wl_listener request_activate;
struct wl_listener request_close;
struct wl_listener handle_destroy;
} on;
/* Compositor side state updates */
struct {
struct wl_listener new_app_id;
struct wl_listener new_title;
struct wl_listener new_outputs;
struct wl_listener maximized;
struct wl_listener minimized;
struct wl_listener fullscreened;
struct wl_listener activated;
} on_view;
/* Internal signals */
struct {
struct wl_listener toplevel_parent;
struct wl_listener toplevel_destroy;
} on_foreign_toplevel;
} wlr_toplevel;
struct ext_foreign_toplevel {
struct wlr_ext_foreign_toplevel_handle_v1 *handle;
/* Client side events */
struct {
struct wl_listener handle_destroy;
} on;
/* Compositor side state updates */
struct {
struct wl_listener new_app_id;
struct wl_listener new_title;
} on_view;
/* Internal signals */
struct {
struct wl_listener toplevel_destroy;
} on_foreign_toplevel;
} ext_toplevel;
/* TODO: add struct xdg_x11_mapped_toplevel at some point */
struct {
struct wl_signal toplevel_parent; /* struct view *parent */
struct wl_signal toplevel_destroy;
} events;
};
void ext_foreign_toplevel_init(struct foreign_toplevel *toplevel);
void wlr_foreign_toplevel_init(struct foreign_toplevel *toplevel);
void foreign_request_minimize(struct foreign_toplevel *toplevel, bool minimized);
void foreign_request_maximize(struct foreign_toplevel *toplevel, enum view_axis axis);
void foreign_request_fullscreen(struct foreign_toplevel *toplevel, bool fullscreen);
void foreign_request_activate(struct foreign_toplevel *toplevel);
void foreign_request_close(struct foreign_toplevel *toplevel);
#endif /* LABWC_FOREIGN_TOPLEVEL_INTERNAL_H */

View file

@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_EXT_FOREIGN_TOPLEVEL_H
#define LABWC_EXT_FOREIGN_TOPLEVEL_H
#include <wayland-server-core.h>
struct ext_foreign_toplevel {
struct view *view;
struct wlr_ext_foreign_toplevel_handle_v1 *handle;
/* Client side events */
struct {
struct wl_listener handle_destroy;
} on;
/* Compositor side state updates */
struct {
struct wl_listener new_app_id;
struct wl_listener new_title;
} on_view;
};
void ext_foreign_toplevel_init(struct ext_foreign_toplevel *ext_toplevel,
struct view *view);
void ext_foreign_toplevel_finish(struct ext_foreign_toplevel *ext_toplevel);
#endif /* LABWC_EXT_FOREIGN_TOPLEVEL_H */

View file

@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_WLR_FOREIGN_TOPLEVEL_H
#define LABWC_WLR_FOREIGN_TOPLEVEL_H
#include <wayland-server-core.h>
struct wlr_foreign_toplevel {
struct view *view;
struct wlr_foreign_toplevel_handle_v1 *handle;
/* Client side events */
struct {
struct wl_listener request_maximize;
struct wl_listener request_minimize;
struct wl_listener request_fullscreen;
struct wl_listener request_activate;
struct wl_listener request_close;
struct wl_listener handle_destroy;
} on;
/* Compositor side state updates */
struct {
struct wl_listener new_app_id;
struct wl_listener new_title;
struct wl_listener new_outputs;
struct wl_listener maximized;
struct wl_listener minimized;
struct wl_listener fullscreened;
struct wl_listener activated;
} on_view;
};
void wlr_foreign_toplevel_init(struct wlr_foreign_toplevel *wlr_toplevel,
struct view *view);
void wlr_foreign_toplevel_set_parent(struct wlr_foreign_toplevel *wlr_toplevel,
struct wlr_foreign_toplevel *parent);
void wlr_foreign_toplevel_finish(struct wlr_foreign_toplevel *wlr_toplevel);
#endif /* LABWC_WLR_FOREIGN_TOPLEVEL_H */