atagen

monolith

public
Star0
Watch0
53111dd60132f6f8f83b508cc035f9509924e231
1
ssh://brewery@pls.lobotomise.me:33/atagen/monolith.git

Blame: crates/protocols/src/toplevel.rs

17d5669ab74batagen2026-10-17 01:14 UTC1
//! wlr-foreign-toplevel-management-v1, for taskbars and window titles in
17d5669ab74batagen2026-10-17 01:14 UTC2
//! bars. Like ext-workspace, the compositor publishes a snapshot of its
17d5669ab74batagen2026-10-17 01:14 UTC3
//! windows and each client is sent the difference from what it has seen.
17d5669ab74batagen2026-10-17 01:14 UTC4
17d5669ab74batagen2026-10-17 01:14 UTC5
use smithay::output::Output;
17d5669ab74batagen2026-10-17 01:14 UTC6
use smithay::reexports::wayland_protocols_wlr::foreign_toplevel::v1::server::{
17d5669ab74batagen2026-10-17 01:14 UTC7
    zwlr_foreign_toplevel_handle_v1::{self, ZwlrForeignToplevelHandleV1},
17d5669ab74batagen2026-10-17 01:14 UTC8
    zwlr_foreign_toplevel_manager_v1::{self, ZwlrForeignToplevelManagerV1},
17d5669ab74batagen2026-10-17 01:14 UTC9
};
17d5669ab74batagen2026-10-17 01:14 UTC10
use smithay::reexports::wayland_server::backend::{ClientId, GlobalId};
17d5669ab74batagen2026-10-17 01:14 UTC11
use smithay::reexports::wayland_server::protocol::wl_output::WlOutput;
17d5669ab74batagen2026-10-17 01:14 UTC12
use smithay::reexports::wayland_server::{
17d5669ab74batagen2026-10-17 01:14 UTC13
    Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
17d5669ab74batagen2026-10-17 01:14 UTC14
};
17d5669ab74batagen2026-10-17 01:14 UTC15
use smithay::wayland::{Dispatch2, GlobalDispatch2};
17d5669ab74batagen2026-10-17 01:14 UTC16
17d5669ab74batagen2026-10-17 01:14 UTC17
#[derive(Clone, Debug, Default, PartialEq)]
17d5669ab74batagen2026-10-17 01:14 UTC18
pub struct Snapshot {
17d5669ab74batagen2026-10-17 01:14 UTC19
    pub toplevels: Vec<Toplevel>,
17d5669ab74batagen2026-10-17 01:14 UTC20
}
17d5669ab74batagen2026-10-17 01:14 UTC21
17d5669ab74batagen2026-10-17 01:14 UTC22
#[derive(Clone, Debug, PartialEq)]
17d5669ab74batagen2026-10-17 01:14 UTC23
pub struct Toplevel {
17d5669ab74batagen2026-10-17 01:14 UTC24
    /// Stable for the window's lifetime.
17d5669ab74batagen2026-10-17 01:14 UTC25
    pub key: u64,
17d5669ab74batagen2026-10-17 01:14 UTC26
    pub title: String,
17d5669ab74batagen2026-10-17 01:14 UTC27
    pub app_id: String,
17d5669ab74batagen2026-10-17 01:14 UTC28
    pub outputs: Vec<Output>,
17d5669ab74batagen2026-10-17 01:14 UTC29
    pub activated: bool,
17d5669ab74batagen2026-10-17 01:14 UTC30
    pub maximized: bool,
17d5669ab74batagen2026-10-17 01:14 UTC31
    pub fullscreen: bool,
17d5669ab74batagen2026-10-17 01:14 UTC32
}
17d5669ab74batagen2026-10-17 01:14 UTC33
17d5669ab74batagen2026-10-17 01:14 UTC34
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
17d5669ab74batagen2026-10-17 01:14 UTC35
pub enum Action {
17d5669ab74batagen2026-10-17 01:14 UTC36
    Activate(u64),
17d5669ab74batagen2026-10-17 01:14 UTC37
    Close(u64),
17d5669ab74batagen2026-10-17 01:14 UTC38
    Maximize(u64, bool),
17d5669ab74batagen2026-10-17 01:14 UTC39
    Fullscreen(u64, bool),
17d5669ab74batagen2026-10-17 01:14 UTC40
}
17d5669ab74batagen2026-10-17 01:14 UTC41
17d5669ab74batagen2026-10-17 01:14 UTC42
pub trait ForeignToplevelHandler {
17d5669ab74batagen2026-10-17 01:14 UTC43
    fn foreign_toplevel_state(&mut self) -> &mut ForeignToplevelState;
17d5669ab74batagen2026-10-17 01:14 UTC44
    fn foreign_toplevel_action(&mut self, action: Action);
17d5669ab74batagen2026-10-17 01:14 UTC45
}
17d5669ab74batagen2026-10-17 01:14 UTC46
17d5669ab74batagen2026-10-17 01:14 UTC47
struct Sent {
17d5669ab74batagen2026-10-17 01:14 UTC48
    handle: ZwlrForeignToplevelHandleV1,
17d5669ab74batagen2026-10-17 01:14 UTC49
    last: Toplevel,
17d5669ab74batagen2026-10-17 01:14 UTC50
    outputs: Vec<WlOutput>,
17d5669ab74batagen2026-10-17 01:14 UTC51
}
17d5669ab74batagen2026-10-17 01:14 UTC52
17d5669ab74batagen2026-10-17 01:14 UTC53
struct Manager {
17d5669ab74batagen2026-10-17 01:14 UTC54
    handle: ZwlrForeignToplevelManagerV1,
17d5669ab74batagen2026-10-17 01:14 UTC55
    toplevels: Vec<Sent>,
17d5669ab74batagen2026-10-17 01:14 UTC56
}
17d5669ab74batagen2026-10-17 01:14 UTC57
17d5669ab74batagen2026-10-17 01:14 UTC58
pub struct ForeignToplevelState {
17d5669ab74batagen2026-10-17 01:14 UTC59
    global: GlobalId,
17d5669ab74batagen2026-10-17 01:14 UTC60
    managers: Vec<Manager>,
17d5669ab74batagen2026-10-17 01:14 UTC61
    snapshot: Snapshot,
17d5669ab74batagen2026-10-17 01:14 UTC62
}
17d5669ab74batagen2026-10-17 01:14 UTC63
17d5669ab74batagen2026-10-17 01:14 UTC64
pub struct ManagerGlobal;
17d5669ab74batagen2026-10-17 01:14 UTC65
17d5669ab74batagen2026-10-17 01:14 UTC66
pub struct ManagerData;
17d5669ab74batagen2026-10-17 01:14 UTC67
17d5669ab74batagen2026-10-17 01:14 UTC68
pub struct HandleData {
17d5669ab74batagen2026-10-17 01:14 UTC69
    key: u64,
17d5669ab74batagen2026-10-17 01:14 UTC70
}
17d5669ab74batagen2026-10-17 01:14 UTC71
17d5669ab74batagen2026-10-17 01:14 UTC72
impl ForeignToplevelState {
17d5669ab74batagen2026-10-17 01:14 UTC73
    pub fn new<D>(dh: &DisplayHandle) -> Self
17d5669ab74batagen2026-10-17 01:14 UTC74
    where
17d5669ab74batagen2026-10-17 01:14 UTC75
        D: GlobalDispatch<ZwlrForeignToplevelManagerV1, ManagerGlobal> + 'static,
17d5669ab74batagen2026-10-17 01:14 UTC76
    {
17d5669ab74batagen2026-10-17 01:14 UTC77
        Self {
17d5669ab74batagen2026-10-17 01:14 UTC78
            global: dh.create_global::<D, ZwlrForeignToplevelManagerV1, _>(3, ManagerGlobal),
17d5669ab74batagen2026-10-17 01:14 UTC79
            managers: Vec::new(),
17d5669ab74batagen2026-10-17 01:14 UTC80
            snapshot: Snapshot::default(),
17d5669ab74batagen2026-10-17 01:14 UTC81
        }
17d5669ab74batagen2026-10-17 01:14 UTC82
    }
17d5669ab74batagen2026-10-17 01:14 UTC83
17d5669ab74batagen2026-10-17 01:14 UTC84
    pub fn global(&self) -> GlobalId {
17d5669ab74batagen2026-10-17 01:14 UTC85
        self.global.clone()
17d5669ab74batagen2026-10-17 01:14 UTC86
    }
17d5669ab74batagen2026-10-17 01:14 UTC87
17d5669ab74batagen2026-10-17 01:14 UTC88
    pub fn has_clients(&self) -> bool {
17d5669ab74batagen2026-10-17 01:14 UTC89
        !self.managers.is_empty()
17d5669ab74batagen2026-10-17 01:14 UTC90
    }
17d5669ab74batagen2026-10-17 01:14 UTC91
17d5669ab74batagen2026-10-17 01:14 UTC92
    pub fn update<D>(&mut self, dh: &DisplayHandle, snapshot: Snapshot)
17d5669ab74batagen2026-10-17 01:14 UTC93
    where
17d5669ab74batagen2026-10-17 01:14 UTC94
        D: Dispatch<ZwlrForeignToplevelHandleV1, HandleData> + 'static,
17d5669ab74batagen2026-10-17 01:14 UTC95
    {
17d5669ab74batagen2026-10-17 01:14 UTC96
        self.snapshot = snapshot;
17d5669ab74batagen2026-10-17 01:14 UTC97
        self.managers.retain(|m| m.handle.is_alive());
17d5669ab74batagen2026-10-17 01:14 UTC98
        for m in &mut self.managers {
17d5669ab74batagen2026-10-17 01:14 UTC99
            sync::<D>(dh, m, &self.snapshot);
17d5669ab74batagen2026-10-17 01:14 UTC100
        }
17d5669ab74batagen2026-10-17 01:14 UTC101
    }
17d5669ab74batagen2026-10-17 01:14 UTC102
}
17d5669ab74batagen2026-10-17 01:14 UTC103
17d5669ab74batagen2026-10-17 01:14 UTC104
fn sync<D>(dh: &DisplayHandle, m: &mut Manager, snap: &Snapshot)
17d5669ab74batagen2026-10-17 01:14 UTC105
where
17d5669ab74batagen2026-10-17 01:14 UTC106
    D: Dispatch<ZwlrForeignToplevelHandleV1, HandleData> + 'static,
17d5669ab74batagen2026-10-17 01:14 UTC107
{
17d5669ab74batagen2026-10-17 01:14 UTC108
    let Ok(client) = dh.get_client(m.handle.id()) else {
17d5669ab74batagen2026-10-17 01:14 UTC109
        return;
17d5669ab74batagen2026-10-17 01:14 UTC110
    };
17d5669ab74batagen2026-10-17 01:14 UTC111
    m.toplevels.retain(|t| {
17d5669ab74batagen2026-10-17 01:14 UTC112
        let keep = snap.toplevels.iter().any(|s| s.key == t.last.key);
17d5669ab74batagen2026-10-17 01:14 UTC113
        if !keep {
17d5669ab74batagen2026-10-17 01:14 UTC114
            t.handle.closed();
17d5669ab74batagen2026-10-17 01:14 UTC115
        }
17d5669ab74batagen2026-10-17 01:14 UTC116
        keep
17d5669ab74batagen2026-10-17 01:14 UTC117
    });
17d5669ab74batagen2026-10-17 01:14 UTC118
    for top in &snap.toplevels {
17d5669ab74batagen2026-10-17 01:14 UTC119
        let i = match m.toplevels.iter().position(|t| t.last.key == top.key) {
17d5669ab74batagen2026-10-17 01:14 UTC120
            Some(i) => i,
17d5669ab74batagen2026-10-17 01:14 UTC121
            None => {
17d5669ab74batagen2026-10-17 01:14 UTC122
                let Ok(handle) = client.create_resource::<ZwlrForeignToplevelHandleV1, _, D>(
17d5669ab74batagen2026-10-17 01:14 UTC123
                    dh,
17d5669ab74batagen2026-10-17 01:14 UTC124
                    m.handle.version(),
17d5669ab74batagen2026-10-17 01:14 UTC125
                    HandleData { key: top.key },
17d5669ab74batagen2026-10-17 01:14 UTC126
                ) else {
17d5669ab74batagen2026-10-17 01:14 UTC127
                    continue;
17d5669ab74batagen2026-10-17 01:14 UTC128
                };
17d5669ab74batagen2026-10-17 01:14 UTC129
                m.handle.toplevel(&handle);
17d5669ab74batagen2026-10-17 01:14 UTC130
                send_props(&handle, None, top);
17d5669ab74batagen2026-10-17 01:14 UTC131
                m.toplevels.push(Sent {
17d5669ab74batagen2026-10-17 01:14 UTC132
                    handle,
17d5669ab74batagen2026-10-17 01:14 UTC133
                    last: top.clone(),
17d5669ab74batagen2026-10-17 01:14 UTC134
                    outputs: Vec::new(),
17d5669ab74batagen2026-10-17 01:14 UTC135
                });
17d5669ab74batagen2026-10-17 01:14 UTC136
                let sent = m.toplevels.last_mut().expect("just pushed");
17d5669ab74batagen2026-10-17 01:14 UTC137
                sync_outputs(&client, sent, top);
17d5669ab74batagen2026-10-17 01:14 UTC138
                sent.handle.done();
17d5669ab74batagen2026-10-17 01:14 UTC139
                continue;
17d5669ab74batagen2026-10-17 01:14 UTC140
            }
17d5669ab74batagen2026-10-17 01:14 UTC141
        };
17d5669ab74batagen2026-10-17 01:14 UTC142
        let sent = &mut m.toplevels[i];
17d5669ab74batagen2026-10-17 01:14 UTC143
        let mut changed = sync_outputs(&client, sent, top);
17d5669ab74batagen2026-10-17 01:14 UTC144
        if sent.last != *top {
17d5669ab74batagen2026-10-17 01:14 UTC145
            send_props(&sent.handle, Some(&sent.last), top);
17d5669ab74batagen2026-10-17 01:14 UTC146
            sent.last = top.clone();
17d5669ab74batagen2026-10-17 01:14 UTC147
            changed = true;
17d5669ab74batagen2026-10-17 01:14 UTC148
        }
17d5669ab74batagen2026-10-17 01:14 UTC149
        if changed {
17d5669ab74batagen2026-10-17 01:14 UTC150
            sent.handle.done();
17d5669ab74batagen2026-10-17 01:14 UTC151
        }
17d5669ab74batagen2026-10-17 01:14 UTC152
    }
17d5669ab74batagen2026-10-17 01:14 UTC153
}
17d5669ab74batagen2026-10-17 01:14 UTC154
17d5669ab74batagen2026-10-17 01:14 UTC155
/// Sends output enter and leave for the client's wl_outputs. Returns
17d5669ab74batagen2026-10-17 01:14 UTC156
/// whether anything was sent.
17d5669ab74batagen2026-10-17 01:14 UTC157
fn sync_outputs(client: &Client, sent: &mut Sent, top: &Toplevel) -> bool {
17d5669ab74batagen2026-10-17 01:14 UTC158
    let want: Vec<WlOutput> = top
17d5669ab74batagen2026-10-17 01:14 UTC159
        .outputs
17d5669ab74batagen2026-10-17 01:14 UTC160
        .iter()
17d5669ab74batagen2026-10-17 01:14 UTC161
        .flat_map(|o| o.client_outputs(client))
17d5669ab74batagen2026-10-17 01:14 UTC162
        .collect();
17d5669ab74batagen2026-10-17 01:14 UTC163
    let mut changed = false;
17d5669ab74batagen2026-10-17 01:14 UTC164
    sent.outputs.retain(|o| {
17d5669ab74batagen2026-10-17 01:14 UTC165
        let keep = o.is_alive() && want.contains(o);
17d5669ab74batagen2026-10-17 01:14 UTC166
        if !keep && o.is_alive() {
17d5669ab74batagen2026-10-17 01:14 UTC167
            sent.handle.output_leave(o);
17d5669ab74batagen2026-10-17 01:14 UTC168
            changed = true;
17d5669ab74batagen2026-10-17 01:14 UTC169
        }
17d5669ab74batagen2026-10-17 01:14 UTC170
        keep
17d5669ab74batagen2026-10-17 01:14 UTC171
    });
17d5669ab74batagen2026-10-17 01:14 UTC172
    for wl in want {
17d5669ab74batagen2026-10-17 01:14 UTC173
        if !sent.outputs.contains(&wl) {
17d5669ab74batagen2026-10-17 01:14 UTC174
            sent.handle.output_enter(&wl);
17d5669ab74batagen2026-10-17 01:14 UTC175
            sent.outputs.push(wl);
17d5669ab74batagen2026-10-17 01:14 UTC176
            changed = true;
17d5669ab74batagen2026-10-17 01:14 UTC177
        }
17d5669ab74batagen2026-10-17 01:14 UTC178
    }
17d5669ab74batagen2026-10-17 01:14 UTC179
    changed
17d5669ab74batagen2026-10-17 01:14 UTC180
}
17d5669ab74batagen2026-10-17 01:14 UTC181
17d5669ab74batagen2026-10-17 01:14 UTC182
fn send_props(h: &ZwlrForeignToplevelHandleV1, old: Option<&Toplevel>, new: &Toplevel) {
17d5669ab74batagen2026-10-17 01:14 UTC183
    if old.is_none_or(|o| o.title != new.title) {
17d5669ab74batagen2026-10-17 01:14 UTC184
        h.title(new.title.clone());
17d5669ab74batagen2026-10-17 01:14 UTC185
    }
17d5669ab74batagen2026-10-17 01:14 UTC186
    if old.is_none_or(|o| o.app_id != new.app_id) {
17d5669ab74batagen2026-10-17 01:14 UTC187
        h.app_id(new.app_id.clone());
17d5669ab74batagen2026-10-17 01:14 UTC188
    }
17d5669ab74batagen2026-10-17 01:14 UTC189
    let states = |t: &Toplevel| {
17d5669ab74batagen2026-10-17 01:14 UTC190
        let mut s: Vec<u32> = Vec::new();
17d5669ab74batagen2026-10-17 01:14 UTC191
        if t.maximized {
17d5669ab74batagen2026-10-17 01:14 UTC192
            s.push(zwlr_foreign_toplevel_handle_v1::State::Maximized as u32);
17d5669ab74batagen2026-10-17 01:14 UTC193
        }
17d5669ab74batagen2026-10-17 01:14 UTC194
        if t.activated {
17d5669ab74batagen2026-10-17 01:14 UTC195
            s.push(zwlr_foreign_toplevel_handle_v1::State::Activated as u32);
17d5669ab74batagen2026-10-17 01:14 UTC196
        }
17d5669ab74batagen2026-10-17 01:14 UTC197
        if t.fullscreen && h.version() >= 2 {
17d5669ab74batagen2026-10-17 01:14 UTC198
            s.push(zwlr_foreign_toplevel_handle_v1::State::Fullscreen as u32);
17d5669ab74batagen2026-10-17 01:14 UTC199
        }
17d5669ab74batagen2026-10-17 01:14 UTC200
        s
17d5669ab74batagen2026-10-17 01:14 UTC201
    };
17d5669ab74batagen2026-10-17 01:14 UTC202
    if old.is_none_or(|o| states(o) != states(new)) {
17d5669ab74batagen2026-10-17 01:14 UTC203
        h.state(states(new).iter().flat_map(|s| s.to_ne_bytes()).collect());
17d5669ab74batagen2026-10-17 01:14 UTC204
    }
17d5669ab74batagen2026-10-17 01:14 UTC205
}
17d5669ab74batagen2026-10-17 01:14 UTC206
17d5669ab74batagen2026-10-17 01:14 UTC207
impl<D> GlobalDispatch2<ZwlrForeignToplevelManagerV1, D> for ManagerGlobal
17d5669ab74batagen2026-10-17 01:14 UTC208
where
17d5669ab74batagen2026-10-17 01:14 UTC209
    D: ForeignToplevelHandler
17d5669ab74batagen2026-10-17 01:14 UTC210
        + Dispatch<ZwlrForeignToplevelManagerV1, ManagerData>
17d5669ab74batagen2026-10-17 01:14 UTC211
        + Dispatch<ZwlrForeignToplevelHandleV1, HandleData>
17d5669ab74batagen2026-10-17 01:14 UTC212
        + 'static,
17d5669ab74batagen2026-10-17 01:14 UTC213
{
17d5669ab74batagen2026-10-17 01:14 UTC214
    fn bind(
17d5669ab74batagen2026-10-17 01:14 UTC215
        &self,
17d5669ab74batagen2026-10-17 01:14 UTC216
        state: &mut D,
17d5669ab74batagen2026-10-17 01:14 UTC217
        dh: &DisplayHandle,
17d5669ab74batagen2026-10-17 01:14 UTC218
        _client: &Client,
17d5669ab74batagen2026-10-17 01:14 UTC219
        resource: New<ZwlrForeignToplevelManagerV1>,
17d5669ab74batagen2026-10-17 01:14 UTC220
        data_init: &mut DataInit<'_, D>,
17d5669ab74batagen2026-10-17 01:14 UTC221
    ) {
17d5669ab74batagen2026-10-17 01:14 UTC222
        let handle = data_init.init(resource, ManagerData);
17d5669ab74batagen2026-10-17 01:14 UTC223
        let s = state.foreign_toplevel_state();
17d5669ab74batagen2026-10-17 01:14 UTC224
        let mut m = Manager {
17d5669ab74batagen2026-10-17 01:14 UTC225
            handle,
17d5669ab74batagen2026-10-17 01:14 UTC226
            toplevels: Vec::new(),
17d5669ab74batagen2026-10-17 01:14 UTC227
        };
17d5669ab74batagen2026-10-17 01:14 UTC228
        sync::<D>(dh, &mut m, &s.snapshot);
17d5669ab74batagen2026-10-17 01:14 UTC229
        s.managers.push(m);
17d5669ab74batagen2026-10-17 01:14 UTC230
    }
17d5669ab74batagen2026-10-17 01:14 UTC231
}
17d5669ab74batagen2026-10-17 01:14 UTC232
17d5669ab74batagen2026-10-17 01:14 UTC233
impl<D: ForeignToplevelHandler> Dispatch2<ZwlrForeignToplevelManagerV1, D> for ManagerData {
17d5669ab74batagen2026-10-17 01:14 UTC234
    fn request(
17d5669ab74batagen2026-10-17 01:14 UTC235
        &self,
17d5669ab74batagen2026-10-17 01:14 UTC236
        state: &mut D,
17d5669ab74batagen2026-10-17 01:14 UTC237
        _client: &Client,
17d5669ab74batagen2026-10-17 01:14 UTC238
        resource: &ZwlrForeignToplevelManagerV1,
17d5669ab74batagen2026-10-17 01:14 UTC239
        request: zwlr_foreign_toplevel_manager_v1::Request,
17d5669ab74batagen2026-10-17 01:14 UTC240
        _dh: &DisplayHandle,
17d5669ab74batagen2026-10-17 01:14 UTC241
        _data_init: &mut DataInit<'_, D>,
17d5669ab74batagen2026-10-17 01:14 UTC242
    ) {
17d5669ab74batagen2026-10-17 01:14 UTC243
        if let zwlr_foreign_toplevel_manager_v1::Request::Stop = request {
17d5669ab74batagen2026-10-17 01:14 UTC244
            resource.finished();
17d5669ab74batagen2026-10-17 01:14 UTC245
            state
17d5669ab74batagen2026-10-17 01:14 UTC246
                .foreign_toplevel_state()
17d5669ab74batagen2026-10-17 01:14 UTC247
                .managers
17d5669ab74batagen2026-10-17 01:14 UTC248
                .retain(|m| m.handle != *resource);
17d5669ab74batagen2026-10-17 01:14 UTC249
        }
17d5669ab74batagen2026-10-17 01:14 UTC250
    }
17d5669ab74batagen2026-10-17 01:14 UTC251
17d5669ab74batagen2026-10-17 01:14 UTC252
    fn destroyed(&self, state: &mut D, _client: ClientId, resource: &ZwlrForeignToplevelManagerV1) {
17d5669ab74batagen2026-10-17 01:14 UTC253
        state
17d5669ab74batagen2026-10-17 01:14 UTC254
            .foreign_toplevel_state()
17d5669ab74batagen2026-10-17 01:14 UTC255
            .managers
17d5669ab74batagen2026-10-17 01:14 UTC256
            .retain(|m| m.handle != *resource);
17d5669ab74batagen2026-10-17 01:14 UTC257
    }
17d5669ab74batagen2026-10-17 01:14 UTC258
}
17d5669ab74batagen2026-10-17 01:14 UTC259
17d5669ab74batagen2026-10-17 01:14 UTC260
impl<D: ForeignToplevelHandler> Dispatch2<ZwlrForeignToplevelHandleV1, D> for HandleData {
17d5669ab74batagen2026-10-17 01:14 UTC261
    fn request(
17d5669ab74batagen2026-10-17 01:14 UTC262
        &self,
17d5669ab74batagen2026-10-17 01:14 UTC263
        state: &mut D,
17d5669ab74batagen2026-10-17 01:14 UTC264
        _client: &Client,
17d5669ab74batagen2026-10-17 01:14 UTC265
        _resource: &ZwlrForeignToplevelHandleV1,
17d5669ab74batagen2026-10-17 01:14 UTC266
        request: zwlr_foreign_toplevel_handle_v1::Request,
17d5669ab74batagen2026-10-17 01:14 UTC267
        _dh: &DisplayHandle,
17d5669ab74batagen2026-10-17 01:14 UTC268
        _data_init: &mut DataInit<'_, D>,
17d5669ab74batagen2026-10-17 01:14 UTC269
    ) {
17d5669ab74batagen2026-10-17 01:14 UTC270
        use zwlr_foreign_toplevel_handle_v1::Request;
17d5669ab74batagen2026-10-17 01:14 UTC271
        let action = match request {
17d5669ab74batagen2026-10-17 01:14 UTC272
            Request::Activate { .. } => Action::Activate(self.key),
17d5669ab74batagen2026-10-17 01:14 UTC273
            Request::Close => Action::Close(self.key),
17d5669ab74batagen2026-10-17 01:14 UTC274
            Request::SetMaximized => Action::Maximize(self.key, true),
17d5669ab74batagen2026-10-17 01:14 UTC275
            Request::UnsetMaximized => Action::Maximize(self.key, false),
17d5669ab74batagen2026-10-17 01:14 UTC276
            Request::SetFullscreen { .. } => Action::Fullscreen(self.key, true),
17d5669ab74batagen2026-10-17 01:14 UTC277
            Request::UnsetFullscreen => Action::Fullscreen(self.key, false),
17d5669ab74batagen2026-10-17 01:14 UTC278
            _ => return,
17d5669ab74batagen2026-10-17 01:14 UTC279
        };
17d5669ab74batagen2026-10-17 01:14 UTC280
        state.foreign_toplevel_action(action);
17d5669ab74batagen2026-10-17 01:14 UTC281
    }
17d5669ab74batagen2026-10-17 01:14 UTC282
17d5669ab74batagen2026-10-17 01:14 UTC283
    fn destroyed(&self, state: &mut D, _client: ClientId, resource: &ZwlrForeignToplevelHandleV1) {
17d5669ab74batagen2026-10-17 01:14 UTC284
        for m in &mut state.foreign_toplevel_state().managers {
17d5669ab74batagen2026-10-17 01:14 UTC285
            m.toplevels.retain(|t| t.handle != *resource);
17d5669ab74batagen2026-10-17 01:14 UTC286
        }
17d5669ab74batagen2026-10-17 01:14 UTC287
    }
17d5669ab74batagen2026-10-17 01:14 UTC288
}