Phase 82: wlroots 0.19 compatibility + native Wayland client support
- Add wlr_subcompositor global (required by all modern Wayland clients) - Switch from xdg_shell new_surface to new_toplevel signal (wlroots 0.19 fires new_surface with role=NONE before get_toplevel assigns the role) - Defer initial xdg_surface configure to first client commit via surface->events.commit listener (surface must be initialized first) - Defer xdg_decoration set_mode to first commit (set_mode internally calls schedule_configure which asserts initialized) - Wire destroy_listener to toplevel->events.destroy instead of xdg_surface->events.destroy (wlroots asserts toplevel event lists are empty before the toplevel is freed) - Log DISPLAY and WAYLAND_DISPLAY env vars at startup - Add WAYLAND_ROADMAP.md Native Wayland clients (foot, etc.) can now connect, render, and disconnect without crashing the compositor.
This commit is contained in:
parent
da4f662844
commit
288d2ad3a7
|
|
@ -0,0 +1,245 @@
|
|||
# WindowMaker Wayland Port — Roadmap
|
||||
|
||||
Last updated: 2026-05-14
|
||||
|
||||
## Architecture
|
||||
|
||||
WindowMaker 0.96.0 uses a vtable-based backend abstraction (`WMBackend` struct in
|
||||
`src/backend/backend.h`) with ~150+ function pointer slots. Policy code calls
|
||||
`wm_backend->operation(...)` and never touches X11/Wayland APIs directly.
|
||||
|
||||
Two backends:
|
||||
- **X11**: `src/backend/x11/x11_backend.c` (150K)
|
||||
- **Wayland**: `src/backend/wayland/wl_backend.c` (316K, wlroots-based compositor)
|
||||
|
||||
Activation: `WMAKER_USE_WAYLAND=1` env var. Nested mode: `WMAKER_WAYLAND_NESTED=1`.
|
||||
|
||||
Three major libraries:
|
||||
- **src/** — WM core (policy layer, zero Xlib calls remaining)
|
||||
- **WINGs/** — Widget toolkit ("WINGs Is Not GNUstep"), split into `_x11.c` / `_wl.c` backends
|
||||
- **wrlib/** — Raster graphics library (image loading, manipulation, rendering)
|
||||
|
||||
---
|
||||
|
||||
## Completed (as of 2026-05-14)
|
||||
|
||||
- Backend vtable abstraction (150+ slots)
|
||||
- Policy layer fully X11-free (zero direct Xlib calls in WM core)
|
||||
- wlroots compositor (headless + nested modes)
|
||||
- XDG shell + XWayland bridge
|
||||
- Frame rendering (titlebar, buttons, resizebar) via pixman → wlr_scene_buffer
|
||||
- Menu rendering + highlighting + item activation
|
||||
- Root menu from config file
|
||||
- Dock rendering (SHM panel, icon slots, app tracking)
|
||||
- Clip rendering
|
||||
- Background rendering
|
||||
- Mouse input (motion, buttons, scroll, grabs)
|
||||
- Keyboard input (XKB, modifiers, keysym translation)
|
||||
- Interactive move/resize with edge detection + cursor changes
|
||||
- Click-to-focus via hit-testing
|
||||
- Run dialog (WINGs modal loop with compositor tick)
|
||||
- Window manage/unmanage lifecycle (XDG toplevel + XWayland)
|
||||
- Focus delivery (wlr_seat_keyboard_notify_enter)
|
||||
- WINGs Wayland backend (views, fonts/PangoFT2, events/ring buffer, rendering/pixman, colors)
|
||||
- Smoke test suite (30+ tests in tests/wl-smoke-test.sh)
|
||||
|
||||
---
|
||||
|
||||
## Phase A: Core Window Management Gaps
|
||||
|
||||
Priority: HIGH — needed for daily-driver use.
|
||||
|
||||
| # | Task | Key Files | Complexity |
|
||||
|---|------|-----------|------------|
|
||||
| A1 | Stacking (raise/lower via scene graph) | stacking.c, wlr_scene_node_raise/lower | Low |
|
||||
| A2 | Window maximize (full/half/vertical/horizontal) | actions.c, usable area calc | Low-Medium |
|
||||
| A3 | Window shade (titlebar collapse) | actions.c, frame buffer resize | Low |
|
||||
| A4 | Workspace switching (create/destroy/switch) | workspace.c, scene tree reparenting | Medium |
|
||||
| A5 | Alt-Tab window cycling + switch panel | cycling.c, switchpanel.c, vtable switchpanel_enter | Medium |
|
||||
| A6 | Window iconification (minimize) + miniwindow | icon.c, appicon.c, vtable icon_paint/icon_update_pixmap | Medium |
|
||||
| A7 | Window placement algorithms (smart/cascade/random) | placement.c (may already work via vtable) | Low |
|
||||
|
||||
---
|
||||
|
||||
## Phase B: Dock & App Icons
|
||||
|
||||
| # | Task | Key Files | Complexity |
|
||||
|---|------|-----------|------------|
|
||||
| B1 | App icon rendering (load .tiff/.png, render into dock) | appicon.c, wrlib loaders, vtable appicon_show | Medium |
|
||||
| B2 | Dock icon drag & drop (reorder, add/remove) | dock.c DnD handlers | Medium |
|
||||
| B3 | Dock auto-launch on login | dock.c session restore | Low |
|
||||
| B4 | Clip workspace indicator (number, arrows) | dock.c clip paint | Low |
|
||||
| B5 | Drawer support (horizontal dock extension) | dock.c drawer subsystem | Medium |
|
||||
| B6 | Icon bounce on launch | vtable appicon_bounce | Low |
|
||||
|
||||
---
|
||||
|
||||
## Phase C: Visual Polish & Animations
|
||||
|
||||
| # | Task | Key Files | Complexity |
|
||||
|---|------|-----------|------------|
|
||||
| C1 | Slide animations (iconify/deiconify zoom) | vtable slide_window | Medium |
|
||||
| C2 | Menu scrolling (long menus) | menu.c scroll logic | Low |
|
||||
| C3 | Balloon tooltips (dock icon hover) | vtable balloon_show | Low |
|
||||
| C4 | Cursor themes (xcursor loading) | wlr_xcursor_manager | Low |
|
||||
| C5 | Window opacity (NETWM alpha) | vtable netwm_set_opacity | Low |
|
||||
|
||||
---
|
||||
|
||||
## Phase D: WINGs Widgets (for Preferences & Inspectors)
|
||||
|
||||
Core rendering backends exist. Complex widgets need verification/porting:
|
||||
|
||||
| Widget | Needed For | Notes |
|
||||
|--------|-----------|-------|
|
||||
| WMList | File panels, icon chooser | Test |
|
||||
| WMBrowser | File browser in dialogs | Test |
|
||||
| WMColorPanel | Color picker in prefs | May need porting |
|
||||
| WMFontPanel | Font selection | May need porting |
|
||||
| WMFilePanel | Open/save dialogs | Test |
|
||||
| WMTabView | Preferences app tabs | Test |
|
||||
| WMScroller/WMScrollView | Scrollable content | Test |
|
||||
| WMSlider | Preference sliders | Test |
|
||||
| WMPopUpButton | Dropdown menus in prefs | Test |
|
||||
| WMTextField (advanced) | Multi-line editing | Test |
|
||||
| Drag & Drop | Icon DnD, file DnD | Likely needs porting |
|
||||
|
||||
---
|
||||
|
||||
## Phase E: Dialogs & Panels
|
||||
|
||||
| # | Task | Key Files | Complexity |
|
||||
|---|------|-----------|------------|
|
||||
| E1 | Window Inspector (per-window attributes) | winspector.c | High (many widgets) |
|
||||
| E2 | Info Panel (about dialog) | dialog.c | Low |
|
||||
| E3 | Crash Dialog (recovery UI) | dialog.c | Low |
|
||||
| E4 | Icon Chooser (browse icon files) | dialog.c | Medium |
|
||||
| E5 | Preferences App (full GUI) | WPrefs.app/ | High |
|
||||
|
||||
---
|
||||
|
||||
## Phase F: wrlib Wayland Integration
|
||||
|
||||
| # | Task | Description | Complexity |
|
||||
|---|------|-------------|------------|
|
||||
| F1 | RContext for Wayland | pixman-backed RContext without X11 Display | Medium |
|
||||
| F2 | RImage → pixman_image conversion | Direct path without XImage | Low (may exist) |
|
||||
| F3 | Texture rendering verification | Solid, gradient, pixmap textures | Verify |
|
||||
| F4 | Image format loaders | PNG/JPEG/GIF/WebP (X11-independent) | Verify |
|
||||
|
||||
---
|
||||
|
||||
## Phase G: Session & Persistence
|
||||
|
||||
| # | Task | Key Files | Complexity |
|
||||
|---|------|-----------|------------|
|
||||
| G1 | Session save/restore (positions, workspaces) | session.c | Medium |
|
||||
| G2 | Dock state persistence (icon layout) | dock.c state files | Low (may work) |
|
||||
| G3 | Defaults database (~/GNUstep/Defaults/) | defaults.c | Verify |
|
||||
| G4 | Autostart (launch apps from session) | startup.c | Low |
|
||||
|
||||
---
|
||||
|
||||
## Phase H: Advanced Compositor Features
|
||||
|
||||
| # | Task | Description | Complexity |
|
||||
|---|------|-------------|------------|
|
||||
| H1 | Multi-monitor (output layout, per-output workspaces) | wlr_output_layout, screen.c | High |
|
||||
| H2 | HiDPI / output scaling | wlr_output_set_scale, buffer scaling | Medium |
|
||||
| H3 | Gamma control (night light) | Already advertised, wire up | Low |
|
||||
| H4 | Screen lock integration | ext-session-lock-v1 protocol | Medium |
|
||||
| H5 | Clipboard (copy/paste between clients) | wl_data_device (may work via wlroots) | Verify |
|
||||
| H6 | Primary selection | Already advertised | Verify |
|
||||
| H7 | Screencopy (screenshots) | Already advertised | Verify |
|
||||
| H8 | DMA-BUF (GPU buffer sharing) | Already advertised | Verify |
|
||||
| H9 | Input method (IME support) | Already advertised | Medium |
|
||||
|
||||
---
|
||||
|
||||
## Phase I: EWMH / Foreign Toplevel
|
||||
|
||||
| # | Task | Description | Complexity |
|
||||
|---|------|-------------|------------|
|
||||
| I1 | Foreign toplevel list (taskbar integration) | Already advertised, verify events | Low |
|
||||
| I2 | XDG activation (focus stealing prevention) | Wire to policy | Low |
|
||||
| I3 | Idle inhibit (prevent blank during video) | Already advertised | Low |
|
||||
|
||||
---
|
||||
|
||||
## Phase J: DRM/KMS Backend (Native)
|
||||
|
||||
For running without a host compositor:
|
||||
|
||||
| # | Task | Description | Complexity |
|
||||
|---|------|-------------|------------|
|
||||
| J1 | DRM backend | wlr_backend_autocreate | Medium |
|
||||
| J2 | libinput (real hardware input) | wlroots handles this | Low |
|
||||
| J3 | VT switching | wlr_session | Low |
|
||||
| J4 | Multi-GPU | Secondary GPU rendering | High |
|
||||
|
||||
---
|
||||
|
||||
## Suggested Implementation Order
|
||||
|
||||
```
|
||||
NOW (daily-driver basics):
|
||||
A1. Stacking (raise/lower)
|
||||
A2. Maximize
|
||||
A3. Shade
|
||||
A4. Workspace switching
|
||||
A5. Alt-Tab cycling
|
||||
A6. Icon/minimize
|
||||
A7. Placement (verify)
|
||||
|
||||
NEXT (visual completeness):
|
||||
B1. App icon rendering (wrlib → pixman)
|
||||
F1. wrlib RContext for Wayland
|
||||
C1. Slide animations
|
||||
C3. Balloon tooltips
|
||||
|
||||
THEN (full feature parity):
|
||||
D*. Test all WINGs widgets
|
||||
E1. Window Inspector
|
||||
E4. Icon Chooser
|
||||
G*. Session persistence
|
||||
B2-B6. Full dock features
|
||||
|
||||
LATER (production-ready):
|
||||
H1. Multi-monitor
|
||||
H2. HiDPI
|
||||
J*. DRM/KMS native backend
|
||||
E5. WPrefs app
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Technical Notes
|
||||
|
||||
1. **Rendering pattern**: pixman_image_t → wlr_scene_buffer → position in scene graph
|
||||
2. **wrlib is mostly X11-independent** — only context.c and convert.c touch X11
|
||||
3. **WINGs complex widgets** are the hardest remaining work (subtle X11 assumptions in events/coords)
|
||||
4. **wlroots handles compositor plumbing** — protocols advertised, work is wiring to policy
|
||||
5. **wl_backend.c (316K) should be split** into wl_frame.c, wl_menu.c, wl_input.c, wl_toplevel.c, wl_output.c as complexity grows
|
||||
6. **Many vtable slots are no-ops** — stubs exist, need implementation following the pixman→scene pattern
|
||||
|
||||
---
|
||||
|
||||
## Key Source Files Reference
|
||||
|
||||
| File | Size | Purpose |
|
||||
|------|------|---------|
|
||||
| src/backend/backend.h | 74K | Vtable definition |
|
||||
| src/backend/backend_types.h | 16K | Backend-neutral types |
|
||||
| src/backend/wayland/wl_backend.c | 316K | Wayland compositor |
|
||||
| src/backend/x11/x11_backend.c | 150K | X11 backend |
|
||||
| src/window.c | 83K | Window management |
|
||||
| src/dock.c | 130K | Dock/Clip/Drawers |
|
||||
| src/menu.c | 61K | Menu system |
|
||||
| src/actions.c | 68K | Window actions |
|
||||
| src/defaults.c | 102K | Preferences/config |
|
||||
| src/event.c | 61K | Event dispatch |
|
||||
| src/moveres.c | 67K | Move/resize |
|
||||
| src/wmspec.c | 61K | EWMH compliance |
|
||||
| src/main.c | 22K | Entry point |
|
||||
| WINGs/WINGs.h | 56K | Toolkit public API |
|
||||
| wrlib/wraster.h | 17K | Raster lib public API |
|
||||
|
|
@ -119,6 +119,7 @@
|
|||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/interfaces/wlr_output.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_subcompositor.h>
|
||||
#include <wlr/types/wlr_data_device.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
|
|
@ -241,6 +242,7 @@ struct wl_toplevel_view {
|
|||
struct wl_listener request_fullscreen_listener;/* Phase 16 */
|
||||
struct wl_listener request_minimize_listener; /* Phase 16 */
|
||||
struct wl_listener set_app_id_listener; /* Phase 16 */
|
||||
struct wl_listener commit_listener; /* initial configure */
|
||||
/* Phase 17: XWayland — set for X11 windows, NULL for XDG toplevels. */
|
||||
struct wlr_xwayland_surface *xw_surface;
|
||||
/* Path 1: geometry listener — keeps scene node in sync when X11 window moves. */
|
||||
|
|
@ -1091,6 +1093,7 @@ handle_toplevel_destroy(struct wl_listener *listener, void *data)
|
|||
wl_list_remove(&view->request_fullscreen_listener.link);
|
||||
wl_list_remove(&view->request_minimize_listener.link);
|
||||
wl_list_remove(&view->set_app_id_listener.link);
|
||||
wl_list_remove(&view->commit_listener.link);
|
||||
wl_list_remove(&view->link);
|
||||
/* Phase 18: remove scene node. */
|
||||
if (view->scene_node) {
|
||||
|
|
@ -1110,17 +1113,47 @@ handle_toplevel_destroy(struct wl_listener *listener, void *data)
|
|||
|
||||
/*
|
||||
* Phase 64: new_toplevel_decoration listener.
|
||||
* Immediately respond with CLIENT_SIDE so clients draw their own
|
||||
* title bars and borders (the Wayland path has no X11 frame rendering).
|
||||
* Respond with CLIENT_SIDE so clients draw their own decorations.
|
||||
* Must defer until the surface is initialized (wlroots 0.19).
|
||||
*/
|
||||
struct wl_deferred_decoration {
|
||||
struct wl_listener commit_listener;
|
||||
struct wlr_xdg_toplevel_decoration_v1 *deco;
|
||||
};
|
||||
|
||||
static void
|
||||
handle_deferred_decoration_commit(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct wl_deferred_decoration *dd =
|
||||
wl_container_of(listener, dd, commit_listener);
|
||||
struct wlr_xdg_surface *surface = dd->deco->toplevel->base;
|
||||
(void)data;
|
||||
|
||||
if (!surface->initial_commit)
|
||||
return;
|
||||
|
||||
wl_list_remove(&dd->commit_listener.link);
|
||||
wlr_xdg_toplevel_decoration_v1_set_mode(dd->deco,
|
||||
WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE);
|
||||
wfree(dd);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_new_toplevel_decoration(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct wlr_xdg_toplevel_decoration_v1 *deco = data;
|
||||
(void)listener;
|
||||
wlr_xdg_toplevel_decoration_v1_set_mode(deco,
|
||||
WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE);
|
||||
wwarning("wl_backend: decoration mode=client_side for new toplevel");
|
||||
|
||||
struct wlr_xdg_surface *surface = deco->toplevel->base;
|
||||
if (surface->initialized) {
|
||||
wlr_xdg_toplevel_decoration_v1_set_mode(deco,
|
||||
WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE);
|
||||
} else {
|
||||
struct wl_deferred_decoration *dd = wmalloc(sizeof(*dd));
|
||||
dd->deco = deco;
|
||||
dd->commit_listener.notify = handle_deferred_decoration_commit;
|
||||
wl_signal_add(&surface->surface->events.commit, &dd->commit_listener);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
@ -1523,30 +1556,43 @@ handle_xwayland_new_surface(struct wl_listener *listener, void *data)
|
|||
}
|
||||
|
||||
/*
|
||||
* Phase 36 / 38: new XDG surface listener.
|
||||
* Allocates a wl_toplevel_view, assigns a synthetic WNativeWindow ID,
|
||||
* wires the three lifecycle listeners, and schedules the initial configure.
|
||||
* handle_xdg_toplevel_initial_commit -- wlroots 0.19 requires that the
|
||||
* initial configure is sent in response to the client's first (empty) commit,
|
||||
* not at new_surface time. The surface is only "initialized" after this
|
||||
* commit, so schedule_configure is safe here.
|
||||
*/
|
||||
static void
|
||||
handle_xdg_new_surface(struct wl_listener *listener, void *data)
|
||||
handle_xdg_toplevel_initial_commit(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct wlr_xdg_surface *xdg_surface = data;
|
||||
struct wl_toplevel_view *view =
|
||||
wl_container_of(listener, view, commit_listener);
|
||||
(void)data;
|
||||
|
||||
if (!view->xdg_surface || !view->xdg_surface->initial_commit)
|
||||
return;
|
||||
|
||||
/* Only need this once — remove ourselves. */
|
||||
wl_list_remove(&view->commit_listener.link);
|
||||
wl_list_init(&view->commit_listener.link);
|
||||
|
||||
wlr_xdg_toplevel_set_size(view->xdg_surface->toplevel, 0, 0);
|
||||
wlr_xdg_surface_schedule_configure(view->xdg_surface);
|
||||
}
|
||||
|
||||
/*
|
||||
* Phase 36 / 38: new XDG toplevel listener (wlroots 0.19+).
|
||||
* Fires when the client calls get_toplevel on an xdg_surface.
|
||||
* Allocates a wl_toplevel_view, assigns a synthetic WNativeWindow ID,
|
||||
* wires lifecycle listeners, and sets up the initial commit handler.
|
||||
*/
|
||||
static void
|
||||
handle_xdg_new_toplevel(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct wlr_xdg_toplevel *toplevel = data;
|
||||
struct wlr_xdg_surface *xdg_surface = toplevel->base;
|
||||
struct wl_toplevel_view *view;
|
||||
(void)listener;
|
||||
|
||||
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
|
||||
/* Phase 66: schedule the initial configure for XDG popups so clients
|
||||
* that use popups (context menus, autocomplete, tooltips) can commit
|
||||
* their first buffer without stalling. We do not manage popups in
|
||||
* the policy layer — they are self-contained transient surfaces. */
|
||||
wlr_xdg_surface_schedule_configure(xdg_surface);
|
||||
wwarning("wl_backend: new XDG popup (scheduled configure)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
|
||||
return;
|
||||
|
||||
view = wmalloc(sizeof(*view));
|
||||
memset(view, 0, sizeof(*view));
|
||||
view->xdg_surface = xdg_surface;
|
||||
|
|
@ -1556,34 +1602,36 @@ handle_xdg_new_surface(struct wl_listener *listener, void *data)
|
|||
view->unmap_listener.notify = handle_toplevel_unmap;
|
||||
view->destroy_listener.notify = handle_toplevel_destroy;
|
||||
view->title_listener.notify = handle_toplevel_title;
|
||||
view->request_move_listener.notify = handle_toplevel_request_move; /* Phase 15 */
|
||||
view->request_resize_listener.notify = handle_toplevel_request_resize; /* Phase 15 */
|
||||
view->request_maximize_listener.notify = handle_toplevel_request_maximize; /* Phase 16 */
|
||||
view->request_fullscreen_listener.notify = handle_toplevel_request_fullscreen; /* Phase 16 */
|
||||
view->request_minimize_listener.notify = handle_toplevel_request_minimize; /* Phase 16 */
|
||||
view->set_app_id_listener.notify = handle_toplevel_set_app_id; /* Phase 16 */
|
||||
view->request_move_listener.notify = handle_toplevel_request_move;
|
||||
view->request_resize_listener.notify = handle_toplevel_request_resize;
|
||||
view->request_maximize_listener.notify = handle_toplevel_request_maximize;
|
||||
view->request_fullscreen_listener.notify = handle_toplevel_request_fullscreen;
|
||||
view->request_minimize_listener.notify = handle_toplevel_request_minimize;
|
||||
view->set_app_id_listener.notify = handle_toplevel_set_app_id;
|
||||
|
||||
wl_signal_add(&xdg_surface->surface->events.map, &view->map_listener);
|
||||
wl_signal_add(&xdg_surface->surface->events.unmap, &view->unmap_listener);
|
||||
wl_signal_add(&xdg_surface->events.destroy, &view->destroy_listener);
|
||||
wl_signal_add(&xdg_surface->toplevel->events.set_title, &view->title_listener);
|
||||
wl_signal_add(&xdg_surface->toplevel->events.request_move, &view->request_move_listener);
|
||||
wl_signal_add(&xdg_surface->toplevel->events.request_resize, &view->request_resize_listener);
|
||||
wl_signal_add(&xdg_surface->toplevel->events.request_maximize, &view->request_maximize_listener);
|
||||
wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &view->request_fullscreen_listener);
|
||||
wl_signal_add(&xdg_surface->toplevel->events.request_minimize, &view->request_minimize_listener);
|
||||
wl_signal_add(&xdg_surface->toplevel->events.set_app_id, &view->set_app_id_listener);
|
||||
wl_signal_add(&toplevel->events.destroy, &view->destroy_listener);
|
||||
wl_signal_add(&toplevel->events.set_title, &view->title_listener);
|
||||
wl_signal_add(&toplevel->events.request_move, &view->request_move_listener);
|
||||
wl_signal_add(&toplevel->events.request_resize, &view->request_resize_listener);
|
||||
wl_signal_add(&toplevel->events.request_maximize, &view->request_maximize_listener);
|
||||
wl_signal_add(&toplevel->events.request_fullscreen, &view->request_fullscreen_listener);
|
||||
wl_signal_add(&toplevel->events.request_minimize, &view->request_minimize_listener);
|
||||
wl_signal_add(&toplevel->events.set_app_id, &view->set_app_id_listener);
|
||||
|
||||
/* wlroots 0.19: send initial configure on the client's first commit,
|
||||
* when the surface becomes initialized. */
|
||||
view->commit_listener.notify = handle_xdg_toplevel_initial_commit;
|
||||
wl_signal_add(&xdg_surface->surface->events.commit, &view->commit_listener);
|
||||
|
||||
wl_list_insert(&wl_state.toplevel_list, &view->link);
|
||||
wl_state.managed_surface_count++;
|
||||
|
||||
wwarning("wl_backend: new XDG toplevel id=0x%lx app_id=%s title=%s",
|
||||
view->id,
|
||||
xdg_surface->toplevel->app_id ? xdg_surface->toplevel->app_id : "(none)",
|
||||
xdg_surface->toplevel->title ? xdg_surface->toplevel->title : "(none)");
|
||||
|
||||
/* Phase 37: initial configure so the client can commit its first buffer. */
|
||||
wlr_xdg_surface_schedule_configure(xdg_surface);
|
||||
toplevel->app_id ? toplevel->app_id : "(none)",
|
||||
toplevel->title ? toplevel->title : "(none)");
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
@ -2157,6 +2205,7 @@ wl_display_open(const char *name)
|
|||
/* Phase 35: advertise core Wayland protocol globals. */
|
||||
wl_state.compositor =
|
||||
wlr_compositor_create(wl_state.display, 6, wl_state.renderer);
|
||||
wlr_subcompositor_create(wl_state.display);
|
||||
wl_state.seat = wlr_seat_create(wl_state.display, "seat0");
|
||||
wl_state.data_device_mgr =
|
||||
wlr_data_device_manager_create(wl_state.display);
|
||||
|
|
@ -2432,9 +2481,9 @@ wl_display_open(const char *name)
|
|||
wl_state.next_synthetic_id = 0x10000000UL;
|
||||
wl_state.managed_surface_count = 0;
|
||||
|
||||
/* Phase 36: listen for new XDG toplevel surfaces. */
|
||||
wl_state.xdg_new_surface_listener.notify = handle_xdg_new_surface;
|
||||
wl_signal_add(&wl_state.xdg_shell->events.new_surface,
|
||||
/* Phase 36: listen for new XDG toplevels (wlroots 0.19+). */
|
||||
wl_state.xdg_new_surface_listener.notify = handle_xdg_new_toplevel;
|
||||
wl_signal_add(&wl_state.xdg_shell->events.new_toplevel,
|
||||
&wl_state.xdg_new_surface_listener);
|
||||
|
||||
/* Path 1: XWayland bridge — start Xwayland eagerly (lazy=false) so that
|
||||
|
|
@ -2949,6 +2998,10 @@ wl_event_loop_run(void)
|
|||
wwarning("wl_backend: X11 event source registered for WINGs dispatch");
|
||||
}
|
||||
|
||||
wwarning("wl_backend: DISPLAY=%s WAYLAND_DISPLAY=%s",
|
||||
getenv("DISPLAY") ? getenv("DISPLAY") : "(unset)",
|
||||
getenv("WAYLAND_DISPLAY") ? getenv("WAYLAND_DISPLAY") : "(unset)");
|
||||
|
||||
/* Phase A: register compositor dispatch callback so WINGs modal loops
|
||||
* (WMRunModalLoop, color panels, etc.) can tick the event loop. */
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue