atagen

monolith

public
Star0
Watch0
e70a8ec6d58d9f99a9b40b24567ab1522f9bf82f
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 update<D>(&mut self, dh: &DisplayHandle, snapshot: Snapshot)
17d5669ab74batagen2026-10-17 01:14 UTC89
    where
17d5669ab74batagen2026-10-17 01:14 UTC90
        D: Dispatch<ZwlrForeignToplevelHandleV1, HandleData> + 'static,
17d5669ab74batagen2026-10-17 01:14 UTC91
    {
17d5669ab74batagen2026-10-17 01:14 UTC92
        self.snapshot = snapshot;
17d5669ab74batagen2026-10-17 01:14 UTC93
        self.managers.retain(|m| m.handle.is_alive());
17d5669ab74batagen2026-10-17 01:14 UTC94
        for m in &mut self.managers {
17d5669ab74batagen2026-10-17 01:14 UTC95
            sync::<D>(dh, m, &self.snapshot);
17d5669ab74batagen2026-10-17 01:14 UTC96
        }
17d5669ab74batagen2026-10-17 01:14 UTC97
    }
17d5669ab74batagen2026-10-17 01:14 UTC98
}
17d5669ab74batagen2026-10-17 01:14 UTC99
17d5669ab74batagen2026-10-17 01:14 UTC100
fn sync<D>(dh: &DisplayHandle, m: &mut Manager, snap: &Snapshot)
17d5669ab74batagen2026-10-17 01:14 UTC101
where
17d5669ab74batagen2026-10-17 01:14 UTC102
    D: Dispatch<ZwlrForeignToplevelHandleV1, HandleData> + 'static,
17d5669ab74batagen2026-10-17 01:14 UTC103
{
17d5669ab74batagen2026-10-17 01:14 UTC104
    let Ok(client) = dh.get_client(m.handle.id()) else {
17d5669ab74batagen2026-10-17 01:14 UTC105
        return;
17d5669ab74batagen2026-10-17 01:14 UTC106
    };
17d5669ab74batagen2026-10-17 01:14 UTC107
    m.toplevels.retain(|t| {
17d5669ab74batagen2026-10-17 01:14 UTC108
        let keep = snap.toplevels.iter().any(|s| s.key == t.last.key);
17d5669ab74batagen2026-10-17 01:14 UTC109
        if !keep {
17d5669ab74batagen2026-10-17 01:14 UTC110
            t.handle.closed();
17d5669ab74batagen2026-10-17 01:14 UTC111
        }
17d5669ab74batagen2026-10-17 01:14 UTC112
        keep
17d5669ab74batagen2026-10-17 01:14 UTC113
    });
17d5669ab74batagen2026-10-17 01:14 UTC114
    for top in &snap.toplevels {
17d5669ab74batagen2026-10-17 01:14 UTC115
        let i = match m.toplevels.iter().position(|t| t.last.key == top.key) {
17d5669ab74batagen2026-10-17 01:14 UTC116
            Some(i) => i,
17d5669ab74batagen2026-10-17 01:14 UTC117
            None => {
17d5669ab74batagen2026-10-17 01:14 UTC118
                let Ok(handle) = client.create_resource::<ZwlrForeignToplevelHandleV1, _, D>(
17d5669ab74batagen2026-10-17 01:14 UTC119
                    dh,
17d5669ab74batagen2026-10-17 01:14 UTC120
                    m.handle.version(),
17d5669ab74batagen2026-10-17 01:14 UTC121
                    HandleData { key: top.key },
17d5669ab74batagen2026-10-17 01:14 UTC122
                ) else {
17d5669ab74batagen2026-10-17 01:14 UTC123
                    continue;
17d5669ab74batagen2026-10-17 01:14 UTC124
                };
17d5669ab74batagen2026-10-17 01:14 UTC125
                m.handle.toplevel(&handle);
17d5669ab74batagen2026-10-17 01:14 UTC126
                send_props(&handle, None, top);
17d5669ab74batagen2026-10-17 01:14 UTC127
                m.toplevels.push(Sent {
17d5669ab74batagen2026-10-17 01:14 UTC128
                    handle,
17d5669ab74batagen2026-10-17 01:14 UTC129
                    last: top.clone(),
17d5669ab74batagen2026-10-17 01:14 UTC130
                    outputs: Vec::new(),
17d5669ab74batagen2026-10-17 01:14 UTC131
                });
17d5669ab74batagen2026-10-17 01:14 UTC132
                let sent = m.toplevels.last_mut().expect("just pushed");
17d5669ab74batagen2026-10-17 01:14 UTC133
                sync_outputs(&client, sent, top);
17d5669ab74batagen2026-10-17 01:14 UTC134
                sent.handle.done();
17d5669ab74batagen2026-10-17 01:14 UTC135
                continue;
17d5669ab74batagen2026-10-17 01:14 UTC136
            }
17d5669ab74batagen2026-10-17 01:14 UTC137
        };
17d5669ab74batagen2026-10-17 01:14 UTC138
        let sent = &mut m.toplevels[i];
17d5669ab74batagen2026-10-17 01:14 UTC139
        let mut changed = sync_outputs(&client, sent, top);
17d5669ab74batagen2026-10-17 01:14 UTC140
        if sent.last != *top {
17d5669ab74batagen2026-10-17 01:14 UTC141
            send_props(&sent.handle, Some(&sent.last), top);
17d5669ab74batagen2026-10-17 01:14 UTC142
            sent.last = top.clone();
17d5669ab74batagen2026-10-17 01:14 UTC143
            changed = true;
17d5669ab74batagen2026-10-17 01:14 UTC144
        }
17d5669ab74batagen2026-10-17 01:14 UTC145
        if changed {
17d5669ab74batagen2026-10-17 01:14 UTC146
            sent.handle.done();
17d5669ab74batagen2026-10-17 01:14 UTC147
        }
17d5669ab74batagen2026-10-17 01:14 UTC148
    }
17d5669ab74batagen2026-10-17 01:14 UTC149
}
17d5669ab74batagen2026-10-17 01:14 UTC150
17d5669ab74batagen2026-10-17 01:14 UTC151
/// Sends output enter and leave for the client's wl_outputs. Returns
17d5669ab74batagen2026-10-17 01:14 UTC152
/// whether anything was sent.
17d5669ab74batagen2026-10-17 01:14 UTC153
fn sync_outputs(client: &Client, sent: &mut Sent, top: &Toplevel) -> bool {
17d5669ab74batagen2026-10-17 01:14 UTC154
    let want: Vec<WlOutput> = top
17d5669ab74batagen2026-10-17 01:14 UTC155
        .outputs
17d5669ab74batagen2026-10-17 01:14 UTC156
        .iter()
17d5669ab74batagen2026-10-17 01:14 UTC157
        .flat_map(|o| o.client_outputs(client))
17d5669ab74batagen2026-10-17 01:14 UTC158
        .collect();
17d5669ab74batagen2026-10-17 01:14 UTC159
    let mut changed = false;
17d5669ab74batagen2026-10-17 01:14 UTC160
    sent.outputs.retain(|o| {
17d5669ab74batagen2026-10-17 01:14 UTC161
        let keep = o.is_alive() && want.contains(o);
17d5669ab74batagen2026-10-17 01:14 UTC162
        if !keep && o.is_alive() {
17d5669ab74batagen2026-10-17 01:14 UTC163
            sent.handle.output_leave(o);
17d5669ab74batagen2026-10-17 01:14 UTC164
            changed = true;
17d5669ab74batagen2026-10-17 01:14 UTC165
        }
17d5669ab74batagen2026-10-17 01:14 UTC166
        keep
17d5669ab74batagen2026-10-17 01:14 UTC167
    });
17d5669ab74batagen2026-10-17 01:14 UTC168
    for wl in want {
17d5669ab74batagen2026-10-17 01:14 UTC169
        if !sent.outputs.contains(&wl) {
17d5669ab74batagen2026-10-17 01:14 UTC170
            sent.handle.output_enter(&wl);
17d5669ab74batagen2026-10-17 01:14 UTC171
            sent.outputs.push(wl);
17d5669ab74batagen2026-10-17 01:14 UTC172
            changed = true;
17d5669ab74batagen2026-10-17 01:14 UTC173
        }
17d5669ab74batagen2026-10-17 01:14 UTC174
    }
17d5669ab74batagen2026-10-17 01:14 UTC175
    changed
17d5669ab74batagen2026-10-17 01:14 UTC176
}
17d5669ab74batagen2026-10-17 01:14 UTC177
17d5669ab74batagen2026-10-17 01:14 UTC178
fn send_props(h: &ZwlrForeignToplevelHandleV1, old: Option<&Toplevel>, new: &Toplevel) {
17d5669ab74batagen2026-10-17 01:14 UTC179
    if old.is_none_or(|o| o.title != new.title) {
17d5669ab74batagen2026-10-17 01:14 UTC180
        h.title(new.title.clone());
17d5669ab74batagen2026-10-17 01:14 UTC181
    }
17d5669ab74batagen2026-10-17 01:14 UTC182
    if old.is_none_or(|o| o.app_id != new.app_id) {
17d5669ab74batagen2026-10-17 01:14 UTC183
        h.app_id(new.app_id.clone());
17d5669ab74batagen2026-10-17 01:14 UTC184
    }
17d5669ab74batagen2026-10-17 01:14 UTC185
    let states = |t: &Toplevel| {
17d5669ab74batagen2026-10-17 01:14 UTC186
        let mut s: Vec<u32> = Vec::new();
17d5669ab74batagen2026-10-17 01:14 UTC187
        if t.maximized {
17d5669ab74batagen2026-10-17 01:14 UTC188
            s.push(zwlr_foreign_toplevel_handle_v1::State::Maximized as u32);
17d5669ab74batagen2026-10-17 01:14 UTC189
        }
17d5669ab74batagen2026-10-17 01:14 UTC190
        if t.activated {
17d5669ab74batagen2026-10-17 01:14 UTC191
            s.push(zwlr_foreign_toplevel_handle_v1::State::Activated as u32);
17d5669ab74batagen2026-10-17 01:14 UTC192
        }
17d5669ab74batagen2026-10-17 01:14 UTC193
        if t.fullscreen && h.version() >= 2 {
17d5669ab74batagen2026-10-17 01:14 UTC194
            s.push(zwlr_foreign_toplevel_handle_v1::State::Fullscreen as u32);
17d5669ab74batagen2026-10-17 01:14 UTC195
        }
17d5669ab74batagen2026-10-17 01:14 UTC196
        s
17d5669ab74batagen2026-10-17 01:14 UTC197
    };
17d5669ab74batagen2026-10-17 01:14 UTC198
    if old.is_none_or(|o| states(o) != states(new)) {
17d5669ab74batagen2026-10-17 01:14 UTC199
        h.state(states(new).iter().flat_map(|s| s.to_ne_bytes()).collect());
17d5669ab74batagen2026-10-17 01:14 UTC200
    }
17d5669ab74batagen2026-10-17 01:14 UTC201
}
17d5669ab74batagen2026-10-17 01:14 UTC202
17d5669ab74batagen2026-10-17 01:14 UTC203
impl<D> GlobalDispatch2<ZwlrForeignToplevelManagerV1, D> for ManagerGlobal
17d5669ab74batagen2026-10-17 01:14 UTC204
where
17d5669ab74batagen2026-10-17 01:14 UTC205
    D: ForeignToplevelHandler
17d5669ab74batagen2026-10-17 01:14 UTC206
        + Dispatch<ZwlrForeignToplevelManagerV1, ManagerData>
17d5669ab74batagen2026-10-17 01:14 UTC207
        + Dispatch<ZwlrForeignToplevelHandleV1, HandleData>
17d5669ab74batagen2026-10-17 01:14 UTC208
        + 'static,
17d5669ab74batagen2026-10-17 01:14 UTC209
{
17d5669ab74batagen2026-10-17 01:14 UTC210
    fn bind(
17d5669ab74batagen2026-10-17 01:14 UTC211
        &self,
17d5669ab74batagen2026-10-17 01:14 UTC212
        state: &mut D,
17d5669ab74batagen2026-10-17 01:14 UTC213
        dh: &DisplayHandle,
17d5669ab74batagen2026-10-17 01:14 UTC214
        _client: &Client,
17d5669ab74batagen2026-10-17 01:14 UTC215
        resource: New<ZwlrForeignToplevelManagerV1>,
17d5669ab74batagen2026-10-17 01:14 UTC216
        data_init: &mut DataInit<'_, D>,
17d5669ab74batagen2026-10-17 01:14 UTC217
    ) {
17d5669ab74batagen2026-10-17 01:14 UTC218
        let handle = data_init.init(resource, ManagerData);
17d5669ab74batagen2026-10-17 01:14 UTC219
        let s = state.foreign_toplevel_state();
17d5669ab74batagen2026-10-17 01:14 UTC220
        let mut m = Manager {
17d5669ab74batagen2026-10-17 01:14 UTC221
            handle,
17d5669ab74batagen2026-10-17 01:14 UTC222
            toplevels: Vec::new(),
17d5669ab74batagen2026-10-17 01:14 UTC223
        };
17d5669ab74batagen2026-10-17 01:14 UTC224
        sync::<D>(dh, &mut m, &s.snapshot);
17d5669ab74batagen2026-10-17 01:14 UTC225
        s.managers.push(m);
17d5669ab74batagen2026-10-17 01:14 UTC226
    }
17d5669ab74batagen2026-10-17 01:14 UTC227
}
17d5669ab74batagen2026-10-17 01:14 UTC228
17d5669ab74batagen2026-10-17 01:14 UTC229
impl<D: ForeignToplevelHandler> Dispatch2<ZwlrForeignToplevelManagerV1, D> for ManagerData {
17d5669ab74batagen2026-10-17 01:14 UTC230
    fn request(
17d5669ab74batagen2026-10-17 01:14 UTC231
        &self,
17d5669ab74batagen2026-10-17 01:14 UTC232
        state: &mut D,
17d5669ab74batagen2026-10-17 01:14 UTC233
        _client: &Client,
17d5669ab74batagen2026-10-17 01:14 UTC234
        resource: &ZwlrForeignToplevelManagerV1,
17d5669ab74batagen2026-10-17 01:14 UTC235
        request: zwlr_foreign_toplevel_manager_v1::Request,
17d5669ab74batagen2026-10-17 01:14 UTC236
        _dh: &DisplayHandle,
17d5669ab74batagen2026-10-17 01:14 UTC237
        _data_init: &mut DataInit<'_, D>,
17d5669ab74batagen2026-10-17 01:14 UTC238
    ) {
17d5669ab74batagen2026-10-17 01:14 UTC239
        if let zwlr_foreign_toplevel_manager_v1::Request::Stop = request {
17d5669ab74batagen2026-10-17 01:14 UTC240
            resource.finished();
17d5669ab74batagen2026-10-17 01:14 UTC241
            state
17d5669ab74batagen2026-10-17 01:14 UTC242
                .foreign_toplevel_state()
17d5669ab74batagen2026-10-17 01:14 UTC243
                .managers
17d5669ab74batagen2026-10-17 01:14 UTC244
                .retain(|m| m.handle != *resource);
17d5669ab74batagen2026-10-17 01:14 UTC245
        }
17d5669ab74batagen2026-10-17 01:14 UTC246
    }
17d5669ab74batagen2026-10-17 01:14 UTC247
17d5669ab74batagen2026-10-17 01:14 UTC248
    fn destroyed(&self, state: &mut D, _client: ClientId, resource: &ZwlrForeignToplevelManagerV1) {
17d5669ab74batagen2026-10-17 01:14 UTC249
        state
17d5669ab74batagen2026-10-17 01:14 UTC250
            .foreign_toplevel_state()
17d5669ab74batagen2026-10-17 01:14 UTC251
            .managers
17d5669ab74batagen2026-10-17 01:14 UTC252
            .retain(|m| m.handle != *resource);
17d5669ab74batagen2026-10-17 01:14 UTC253
    }
17d5669ab74batagen2026-10-17 01:14 UTC254
}
17d5669ab74batagen2026-10-17 01:14 UTC255
17d5669ab74batagen2026-10-17 01:14 UTC256
impl<D: ForeignToplevelHandler> Dispatch2<ZwlrForeignToplevelHandleV1, D> for HandleData {
17d5669ab74batagen2026-10-17 01:14 UTC257
    fn request(
17d5669ab74batagen2026-10-17 01:14 UTC258
        &self,
17d5669ab74batagen2026-10-17 01:14 UTC259
        state: &mut D,
17d5669ab74batagen2026-10-17 01:14 UTC260
        _client: &Client,
17d5669ab74batagen2026-10-17 01:14 UTC261
        _resource: &ZwlrForeignToplevelHandleV1,
17d5669ab74batagen2026-10-17 01:14 UTC262
        request: zwlr_foreign_toplevel_handle_v1::Request,
17d5669ab74batagen2026-10-17 01:14 UTC263
        _dh: &DisplayHandle,
17d5669ab74batagen2026-10-17 01:14 UTC264
        _data_init: &mut DataInit<'_, D>,
17d5669ab74batagen2026-10-17 01:14 UTC265
    ) {
17d5669ab74batagen2026-10-17 01:14 UTC266
        use zwlr_foreign_toplevel_handle_v1::Request;
17d5669ab74batagen2026-10-17 01:14 UTC267
        let action = match request {
17d5669ab74batagen2026-10-17 01:14 UTC268
            Request::Activate { .. } => Action::Activate(self.key),
17d5669ab74batagen2026-10-17 01:14 UTC269
            Request::Close => Action::Close(self.key),
17d5669ab74batagen2026-10-17 01:14 UTC270
            Request::SetMaximized => Action::Maximize(self.key, true),
17d5669ab74batagen2026-10-17 01:14 UTC271
            Request::UnsetMaximized => Action::Maximize(self.key, false),
17d5669ab74batagen2026-10-17 01:14 UTC272
            Request::SetFullscreen { .. } => Action::Fullscreen(self.key, true),
17d5669ab74batagen2026-10-17 01:14 UTC273
            Request::UnsetFullscreen => Action::Fullscreen(self.key, false),
17d5669ab74batagen2026-10-17 01:14 UTC274
            _ => return,
17d5669ab74batagen2026-10-17 01:14 UTC275
        };
17d5669ab74batagen2026-10-17 01:14 UTC276
        state.foreign_toplevel_action(action);
17d5669ab74batagen2026-10-17 01:14 UTC277
    }
17d5669ab74batagen2026-10-17 01:14 UTC278
17d5669ab74batagen2026-10-17 01:14 UTC279
    fn destroyed(&self, state: &mut D, _client: ClientId, resource: &ZwlrForeignToplevelHandleV1) {
17d5669ab74batagen2026-10-17 01:14 UTC280
        for m in &mut state.foreign_toplevel_state().managers {
17d5669ab74batagen2026-10-17 01:14 UTC281
            m.toplevels.retain(|t| t.handle != *resource);
17d5669ab74batagen2026-10-17 01:14 UTC282
        }
17d5669ab74batagen2026-10-17 01:14 UTC283
    }
17d5669ab74batagen2026-10-17 01:14 UTC284
}