From d3f4583c903dc36d93924ce3d2ec8c9ffc57dae5 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Tue, 30 Jan 2024 09:20:49 +0400 Subject: foreign_toplevel: Use OutputHandler to send output_enter on demand --- Cargo.lock | 4 ++-- src/handlers/mod.rs | 10 ++++++++- src/protocols/foreign_toplevel.rs | 47 ++++++++++++++++++++++----------------- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 78fd9803..34dde221 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2716,7 +2716,7 @@ checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "smithay" version = "0.3.0" -source = "git+https://github.com/Smithay/smithay.git#b9f6a478cf462c9274bb366cf62b04cee5a03466" +source = "git+https://github.com/Smithay/smithay.git#125b7972c4b1f0498bce564b25fe72c1cebb0a16" dependencies = [ "appendlist", "bitflags 2.4.2", @@ -2788,7 +2788,7 @@ dependencies = [ [[package]] name = "smithay-drm-extras" version = "0.1.0" -source = "git+https://github.com/Smithay/smithay.git#b9f6a478cf462c9274bb366cf62b04cee5a03466" +source = "git+https://github.com/Smithay/smithay.git#125b7972c4b1f0498bce564b25fe72c1cebb0a16" dependencies = [ "drm", "edid-rs", diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index f0620a5b..0ca5e7bb 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -23,6 +23,7 @@ use smithay::utils::{Logical, Rectangle, Size}; use smithay::wayland::compositor::{send_surface_state, with_states}; use smithay::wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier}; use smithay::wayland::input_method::{InputMethodHandler, PopupSurface}; +use smithay::wayland::output::OutputHandler; use smithay::wayland::pointer_constraints::PointerConstraintsHandler; use smithay::wayland::security_context::{ SecurityContext, SecurityContextHandler, SecurityContextListenerSource, @@ -49,7 +50,9 @@ use smithay::{ use crate::delegate_foreign_toplevel; use crate::niri::{ClientState, State}; -use crate::protocols::foreign_toplevel::{ForeignToplevelHandler, ForeignToplevelManagerState}; +use crate::protocols::foreign_toplevel::{ + self, ForeignToplevelHandler, ForeignToplevelManagerState, +}; use crate::utils::output_size; impl SeatHandler for State { @@ -206,6 +209,11 @@ impl DataControlHandler for State { delegate_data_control!(State); +impl OutputHandler for State { + fn output_bound(&mut self, output: Output, wl_output: WlOutput) { + foreign_toplevel::on_output_bound(self, &output, &wl_output); + } +} delegate_output!(State); delegate_presentation!(State); diff --git a/src/protocols/foreign_toplevel.rs b/src/protocols/foreign_toplevel.rs index f1e37fd2..b574b51c 100644 --- a/src/protocols/foreign_toplevel.rs +++ b/src/protocols/foreign_toplevel.rs @@ -131,6 +131,31 @@ pub fn refresh(state: &mut State) { } } +pub fn on_output_bound(state: &mut State, output: &Output, wl_output: &WlOutput) { + let _span = tracy_client::span!("foreign_toplevel::on_output_bound"); + + let Some(client) = wl_output.client() else { + return; + }; + + let protocol_state = &mut state.niri.foreign_toplevel_state; + for data in protocol_state.toplevels.values_mut() { + if data.output.as_ref() != Some(output) { + continue; + } + + for (instance, outputs) in &mut data.instances { + if instance.client().as_ref() != Some(&client) { + continue; + } + + instance.output_enter(wl_output); + instance.done(); + outputs.push(wl_output.clone()); + } + } +} + fn refresh_toplevel( protocol_state: &mut ForeignToplevelManagerState, wl_surface: &WlSurface, @@ -204,31 +229,13 @@ fn refresh_toplevel( } } } + instance.done(); } } - for (instance, outputs) in &mut data.instances { + for outputs in data.instances.values_mut() { // Clean up dead wl_outputs. outputs.retain(|x| x.is_alive()); - - let mut send_done = something_changed; - - // If the client bound any more wl_outputs, send enter for them. - if let Some(output) = &data.output { - if let Some(client) = instance.client() { - for wl_output in output.client_outputs(&client) { - if !outputs.iter().any(|x| x == &wl_output) { - instance.output_enter(&wl_output); - outputs.push(wl_output); - send_done = true; - } - } - } - } - - if send_done { - instance.done(); - } } } Entry::Vacant(entry) => { -- cgit