Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions cosmic-panel-bin/src/iced/elements/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@ use super::{CosmicMappedInternal, PopupMappedInternal};
use crate::xdg_shell_wrapper::shared_state::GlobalState;

use anyhow::bail;
use smithay::{
input::{
Seat,
dnd::{self, DndFocus},
keyboard::KeyboardTarget,
pointer::PointerTarget,
touch::TouchTarget,
},
reexports::wayland_server::{DisplayHandle, protocol::wl_surface::WlSurface},
utils::IsAlive,
wayland::{seat::WaylandFocus, selection::data_device::WlOfferData},
};
use smithay::input::Seat;
use smithay::input::dnd::{self, DndFocus};
use smithay::input::keyboard::KeyboardTarget;
use smithay::input::pointer::PointerTarget;
use smithay::input::touch::TouchTarget;
use smithay::reexports::wayland_server::DisplayHandle;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::IsAlive;
use smithay::wayland::seat::WaylandFocus;
use smithay::wayland::selection::data_device::WlOfferData;
use std::sync::Arc;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
Expand Down
11 changes: 6 additions & 5 deletions cosmic-panel-bin/src/space/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ use smithay::backend::renderer::element::{AsRenderElements, RenderElement, Under
use smithay::backend::renderer::gles::{GlesError, GlesFrame, GlesRenderer};
use smithay::backend::renderer::{Bind, Color32F, Frame, Renderer};
use smithay::reexports::wayland_server::Resource;
use smithay::utils::{Buffer, IsAlive, Physical, Point, Rectangle, user_data::UserDataMap};
use smithay::utils::user_data::UserDataMap;
use smithay::utils::{Buffer, IsAlive, Physical, Point, Rectangle};
use smithay::wayland::seat::WaylandFocus;

pub(crate) enum PanelRenderElement {
Expand Down Expand Up @@ -134,10 +135,10 @@ impl PanelSpace {
anyhow::bail!("Failed to clear panel.");
};

_ = frame.clear(
Color32F::new(0.0, 0.0, 0.0, 0.0),
&[Rectangle::new((0, 0).into(), dim)],
);
_ = frame.clear(Color32F::new(0.0, 0.0, 0.0, 0.0), &[Rectangle::new(
(0, 0).into(),
dim,
)]);
if let Ok(sync_point) = frame.finish() {
if let Err(err) = sync_point.wait() {
tracing::error!("Error waiting for sync point: {:?}", err);
Expand Down
65 changes: 39 additions & 26 deletions cosmic-panel-bin/src/space/wrapper_space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,6 @@ impl WrapperSpace for PanelSpace {
s_surface: PopupSurface,
positioner: sctk::shell::xdg::XdgPositioner,
positioner_state: PositionerState,
latest_seat: &wl_seat::WlSeat,
latest_serial: u32,
) -> anyhow::Result<()> {
self.apply_positioner_state(&positioner, positioner_state, &s_surface);
let c_wl_surface = compositor_state.create_surface(qh);
Expand Down Expand Up @@ -270,14 +268,7 @@ impl WrapperSpace for PanelSpace {
area = area.saturating_add(r.1.size.w.saturating_mul(r.1.size.h));
input_region.add(0, 0, r.1.size.w, r.1.size.h);
}
// must take a grab on all popups to avoid being closed automatically by focus
// follows cursor...
if area > 1 {
c_popup.xdg_popup().grab(latest_seat, latest_serial);
}
c_wl_surface.set_input_region(Some(input_region.wl_region()));
} else {
c_popup.xdg_popup().grab(latest_seat, latest_serial);
}
let fractional_scale =
fractional_scale_manager.map(|f| f.fractional_scaling(&c_wl_surface, qh));
Expand Down Expand Up @@ -334,6 +325,18 @@ impl WrapperSpace for PanelSpace {
Ok(())
}

fn grab_popup(
&mut self,
popup: PopupSurface,
seat: wl_seat::WlSeat,
serial: u32,
) -> anyhow::Result<()> {
if let Some(p) = self.popups.iter().find(|wp| wp.s_surface == popup) {
p.popup.c_popup.xdg_popup().grab(&seat, serial);
}
Ok(())
}

fn reposition_popup(
&mut self,
popup: PopupSurface,
Expand Down Expand Up @@ -710,13 +713,10 @@ impl WrapperSpace for PanelSpace {
return;
};
if let Err(err) = pman
.update_process_env(
&key,
vec![(
"COSMIC_NOTIFICATIONS".to_string(),
fd.as_raw_fd().to_string(),
)],
)
.update_process_env(&key, vec![(
"COSMIC_NOTIFICATIONS".to_string(),
fd.as_raw_fd().to_string(),
)])
.await
{
error!("Failed to update process env: {}", err);
Expand Down Expand Up @@ -1370,16 +1370,29 @@ impl WrapperSpace for PanelSpace {
}

fn keyboard_leave(&mut self, seat_name: &str, f: Option<c_wl_surface::WlSurface>) {
// if not a leaf, return early
if let Some(surface) = f.as_ref()
&& self.popups.iter().any(|p| p.popup.parent == *surface)
{
return;
}
if self.layer.as_ref().zip(f).is_some_and(|l| l.0.wl_surface() == &l.1)
&& (self.popups.iter().any(|p| p.popup.grab) || self.overflow_popup.is_some())
{
return;
if let Some(surface) = f.as_ref() {
// if not a leaf, return early
if self.popups.iter().any(|p| p.popup.parent == *surface) {
return;
}

if self.layer.as_ref().is_some_and(|l| l.wl_surface() == surface)
&& (self.popups.iter().any(|p| p.popup.grab) || self.overflow_popup.is_some())
{
return;
}

// Ignore event for wl_surface that isn't our layer or popup (i.e. a different
// panel)
if !self.layer.as_ref().is_some_and(|l| l.wl_surface() == surface)
&& !self
.overflow_popup
.as_ref()
.is_some_and(|(p, _)| p.c_popup.wl_surface() == surface)
&& !self.popups.iter().any(|p| p.popup.c_popup.wl_surface() == surface)
{
return;
}
}

self.s_focused_surface.retain(|(_, name)| name != seat_name);
Expand Down
18 changes: 18 additions & 0 deletions cosmic-panel-bin/src/space_container/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,27 @@
//! separate panel space container implements the WrapperSpace abstraction,
//! calling handle events and other methods of its PanelSpaces as necessary

use crate::space::PanelSpace;

mod space_container;
pub(crate) mod toplevel;
pub(crate) mod workspace;
mod wrapper_space;

pub use space_container::*;

fn space_for_client_mut(
space_list: &mut [PanelSpace],
client: Option<wayland_backend::server::ClientId>,
) -> Option<&mut PanelSpace> {
space_list.iter_mut().find(|space| {
space
.clients_center
.lock()
.unwrap()
.iter()
.chain(space.clients_left.lock().unwrap().iter())
.chain(space.clients_right.lock().unwrap().iter())
.any(|c| c.client.as_ref().zip(client.as_ref()).is_some_and(|c| c.0.id() == *c.1))
})
}
13 changes: 3 additions & 10 deletions cosmic-panel-bin/src/space_container/space_container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ use tokio::sync::mpsc;
use tracing::{error, info};
use wayland_server::Resource;

use super::space_for_client_mut;

pub struct SpaceContainer {
pub(crate) connection: Option<Connection>,
pub(crate) config: CosmicPanelContainerConfig,
Expand Down Expand Up @@ -572,16 +574,7 @@ impl SpaceContainer {
// add window to the space with a client that matches the window
let s_client = wlsurface.client().map(|c| c.id());

if let Some(space) = self.space_list.iter_mut().find(|space| {
space
.clients_center
.lock()
.unwrap()
.iter()
.chain(space.clients_left.lock().unwrap().iter())
.chain(space.clients_right.lock().unwrap().iter())
.any(|c| c.client.as_ref().map(|c| c.id()) == s_client)
}) {
if let Some(space) = space_for_client_mut(&mut self.space_list, s_client) {
space.dirty_subsurface(
self.renderer.as_mut(),
compositor_state,
Expand Down
76 changes: 21 additions & 55 deletions cosmic-panel-bin/src/space_container/wrapper_space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use smithay::reexports::wayland_server::{self, Resource};

use crate::space::PanelSpace;

use super::SpaceContainer;
use super::{SpaceContainer, space_for_client_mut};

impl WrapperSpace for SpaceContainer {
type Config = CosmicPanelContainerConfig;
Expand Down Expand Up @@ -299,16 +299,7 @@ impl WrapperSpace for SpaceContainer {
// add window to the space with a client that matches the window
let w_client = s_top_level.toplevel().and_then(|t| t.wl_surface().client().map(|c| c.id()));

if let Some(space) = self.space_list.iter_mut().find(|space| {
space
.clients_center
.lock()
.unwrap()
.iter()
.chain(space.clients_left.lock().unwrap().iter())
.chain(space.clients_right.lock().unwrap().iter())
.any(|c| c.client.as_ref().zip(w_client.as_ref()).is_some_and(|c| c.0.id() == *c.1))
}) {
if let Some(space) = space_for_client_mut(&mut self.space_list, w_client) {
space.add_window(s_top_level);
}
}
Expand All @@ -324,22 +315,11 @@ impl WrapperSpace for SpaceContainer {
s_surface: smithay::wayland::shell::xdg::PopupSurface,
positioner: sctk::shell::xdg::XdgPositioner,
positioner_state: smithay::wayland::shell::xdg::PositionerState,
c_seat: &WlSeat,
last_serial: u32,
) -> anyhow::Result<()> {
// add popup to the space with a client that matches the window
let p_client = s_surface.wl_surface().client().map(|c| c.id());

if let Some(space) = self.space_list.iter_mut().find(|space| {
space
.clients_center
.lock()
.unwrap()
.iter()
.chain(space.clients_left.lock().unwrap().iter())
.chain(space.clients_right.lock().unwrap().iter())
.any(|c| c.client.as_ref().zip(p_client.as_ref()).is_some_and(|c| c.0.id() == *c.1))
}) {
if let Some(space) = space_for_client_mut(&mut self.space_list, p_client) {
space.add_popup(
compositor_state,
fractional_scale_manager,
Expand All @@ -350,14 +330,27 @@ impl WrapperSpace for SpaceContainer {
s_surface,
positioner,
positioner_state,
c_seat,
last_serial,
)
} else {
anyhow::bail!("failed to find a matching panel space for this popup.")
}
}

fn grab_popup(
&mut self,
s_surface: smithay::wayland::shell::xdg::PopupSurface,
seat: WlSeat,
serial: u32,
) -> anyhow::Result<()> {
let p_client = s_surface.wl_surface().client().map(|c| c.id());

if let Some(space) = space_for_client_mut(&mut self.space_list, p_client) {
space.grab_popup(s_surface, seat, serial)
} else {
anyhow::bail!("Failed to find popup with matching client id")
}
}

fn reposition_popup(
&mut self,
popup: smithay::wayland::shell::xdg::PopupSurface,
Expand All @@ -367,16 +360,7 @@ impl WrapperSpace for SpaceContainer {
// add popup to the space with a client that matches the window
let p_client = popup.wl_surface().client().map(|c| c.id());

if let Some(space) = self.space_list.iter_mut().find(|space| {
space
.clients_center
.lock()
.unwrap()
.iter()
.chain(space.clients_left.lock().unwrap().iter())
.chain(space.clients_right.lock().unwrap().iter())
.any(|c| c.client.as_ref().zip(p_client.as_ref()).is_some_and(|c| c.0.id() == *c.1))
}) {
if let Some(space) = space_for_client_mut(&mut self.space_list, p_client) {
space.reposition_popup(popup, positioner_state, token)?
}
anyhow::bail!("Failed to find popup with matching client id")
Expand Down Expand Up @@ -435,16 +419,7 @@ impl WrapperSpace for SpaceContainer {
// add window to the space with a client that matches the window
let w_client = w.client().map(|c| c.id());

if let Some(space) = self.space_list.iter_mut().find(|space| {
space
.clients_center
.lock()
.unwrap()
.iter()
.chain(space.clients_left.lock().unwrap().iter())
.chain(space.clients_right.lock().unwrap().iter())
.any(|c| c.client.as_ref().zip(w_client.as_ref()).is_some_and(|c| c.0.id() == *c.1))
}) {
if let Some(space) = space_for_client_mut(&mut self.space_list, w_client) {
space.dirty_window(dh, w);
}
}
Expand All @@ -457,16 +432,7 @@ impl WrapperSpace for SpaceContainer {
// add window to the space with a client that matches the window
let p_client = w.client().map(|c| c.id());

if let Some(space) = self.space_list.iter_mut().find(|space| {
space
.clients_center
.lock()
.unwrap()
.iter()
.chain(space.clients_left.lock().unwrap().iter())
.chain(space.clients_right.lock().unwrap().iter())
.any(|c| c.client.as_ref().zip(p_client.as_ref()).is_some_and(|c| c.0.id() == *c.1))
}) {
if let Some(space) = space_for_client_mut(&mut self.space_list, p_client) {
space.dirty_popup(dh, w);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,19 @@
use std::time::Instant;

use cctk::wayland_client::protocol::wl_surface::WlSurface;
use sctk::{
data_device_manager::{
data_device::{DataDeviceData, DataDeviceHandler},
data_offer::DataOfferData,
},
reexports::client::{
Proxy,
protocol::{
wl_data_device::WlDataDevice, wl_data_device_manager::DndAction as ClientDndAction,
},
},
seat::pointer::{PointerEvent, PointerEventKind, PointerHandler},
};
use sctk::data_device_manager::data_device::{DataDeviceData, DataDeviceHandler};
use sctk::data_device_manager::data_offer::DataOfferData;
use sctk::reexports::client::Proxy;
use sctk::reexports::client::protocol::wl_data_device::WlDataDevice;
use sctk::reexports::client::protocol::wl_data_device_manager::DndAction as ClientDndAction;
use sctk::seat::pointer::{PointerEvent, PointerEventKind, PointerHandler};
use smallvec::SmallVec;
use smithay::{
input::{
dnd::{DndAction, SourceMetadata},
pointer::GrabStartData,
},
reexports::wayland_server::Resource,
utils::SERIAL_COUNTER,
wayland::{
seat::WaylandFocus,
selection::data_device::{set_data_device_focus, set_data_device_selection},
},
};
use smithay::input::dnd::{DndAction, SourceMetadata};
use smithay::input::pointer::GrabStartData;
use smithay::reexports::wayland_server::Resource;
use smithay::utils::SERIAL_COUNTER;
use smithay::wayland::seat::WaylandFocus;
use smithay::wayland::selection::data_device::{set_data_device_focus, set_data_device_selection};

use crate::xdg_shell_wrapper::client_state::FocusStatus;
use crate::xdg_shell_wrapper::server_state::ServerPointerFocus;
Expand Down
Loading