Use WlOutput instead of output names for matching
With a shared wayland connection between the code here and iced, if we don't bind outputs outselves, we can have `WlOutput`s that match. This simplifies things.
This commit is contained in:
parent
96cd334b81
commit
9598a9f8e4
6 changed files with 53 additions and 142 deletions
72
src/main.rs
72
src/main.rs
|
|
@ -81,9 +81,9 @@ enum Msg {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Workspace {
|
struct Workspace {
|
||||||
name: String,
|
name: String,
|
||||||
img_for_output: HashMap<String, iced::widget::image::Handle>,
|
img_for_output: HashMap<wl_output::WlOutput, iced::widget::image::Handle>,
|
||||||
handle: zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
|
handle: zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
|
||||||
output_names: Vec<String>,
|
outputs: HashSet<wl_output::WlOutput>,
|
||||||
is_active: bool,
|
is_active: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,13 +91,11 @@ struct Workspace {
|
||||||
struct Toplevel {
|
struct Toplevel {
|
||||||
handle: zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
handle: zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||||
info: ToplevelInfo,
|
info: ToplevelInfo,
|
||||||
output_names: HashSet<String>,
|
|
||||||
img: Option<iced::widget::image::Handle>,
|
img: Option<iced::widget::image::Handle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Output {
|
struct Output {
|
||||||
// Output, on the `iced_sctk` Wayland connection
|
|
||||||
handle: wl_output::WlOutput,
|
handle: wl_output::WlOutput,
|
||||||
name: String,
|
name: String,
|
||||||
width: i32,
|
width: i32,
|
||||||
|
|
@ -105,16 +103,17 @@ struct Output {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LayerSurface {
|
struct LayerSurface {
|
||||||
// Output, on the `iced_sctk` Wayland connection
|
|
||||||
output: wl_output::WlOutput,
|
output: wl_output::WlOutput,
|
||||||
output_name: String,
|
|
||||||
// for transitions, would need windows in more than one workspace? But don't capture all of
|
// for transitions, would need windows in more than one workspace? But don't capture all of
|
||||||
// them all the time every frame.
|
// them all the time every frame.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum DragSurface {
|
enum DragSurface {
|
||||||
Workspace { name: String, output_name: String },
|
Workspace {
|
||||||
|
name: String,
|
||||||
|
output: wl_output::WlOutput,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
@ -163,7 +162,6 @@ impl App {
|
||||||
fn create_surface(
|
fn create_surface(
|
||||||
&mut self,
|
&mut self,
|
||||||
output: wl_output::WlOutput,
|
output: wl_output::WlOutput,
|
||||||
output_name: String,
|
|
||||||
width: i32,
|
width: i32,
|
||||||
height: i32,
|
height: i32,
|
||||||
) -> Command<Msg> {
|
) -> Command<Msg> {
|
||||||
|
|
@ -172,7 +170,6 @@ impl App {
|
||||||
id,
|
id,
|
||||||
LayerSurface {
|
LayerSurface {
|
||||||
output: output.clone(),
|
output: output.clone(),
|
||||||
output_name,
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
get_layer_surface(SctkLayerSurfaceSettings {
|
get_layer_surface(SctkLayerSurfaceSettings {
|
||||||
|
|
@ -216,9 +213,7 @@ impl App {
|
||||||
let cmd = Command::batch(
|
let cmd = Command::batch(
|
||||||
outputs
|
outputs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|output| {
|
.map(|output| self.create_surface(output.handle, output.width, output.height))
|
||||||
self.create_surface(output.handle, output.name, output.width, output.height)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
);
|
);
|
||||||
self.update_capture_filter();
|
self.update_capture_filter();
|
||||||
|
|
@ -246,7 +241,7 @@ impl App {
|
||||||
if self.visible {
|
if self.visible {
|
||||||
// XXX handle on wrong connection
|
// XXX handle on wrong connection
|
||||||
capture_filter.workspaces_on_outputs =
|
capture_filter.workspaces_on_outputs =
|
||||||
self.outputs.iter().map(|x| x.name.clone()).collect();
|
self.outputs.iter().map(|x| x.handle.clone()).collect();
|
||||||
capture_filter.toplevels_on_workspaces = self
|
capture_filter.toplevels_on_workspaces = self
|
||||||
.workspaces
|
.workspaces
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -299,12 +294,7 @@ impl Application for App {
|
||||||
height,
|
height,
|
||||||
});
|
});
|
||||||
if self.visible {
|
if self.visible {
|
||||||
return self.create_surface(
|
return self.create_surface(output.clone(), width, height);
|
||||||
output.clone(),
|
|
||||||
name,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -350,7 +340,7 @@ impl Application for App {
|
||||||
wayland::Event::Workspaces(workspaces) => {
|
wayland::Event::Workspaces(workspaces) => {
|
||||||
let old_workspaces = mem::take(&mut self.workspaces);
|
let old_workspaces = mem::take(&mut self.workspaces);
|
||||||
self.workspaces = Vec::new();
|
self.workspaces = Vec::new();
|
||||||
for (output_names, workspace) in workspaces {
|
for (outputs, workspace) in workspaces {
|
||||||
let is_active = workspace.state.contains(&WEnum::Value(
|
let is_active = workspace.state.contains(&WEnum::Value(
|
||||||
zcosmic_workspace_handle_v1::State::Active,
|
zcosmic_workspace_handle_v1::State::Active,
|
||||||
));
|
));
|
||||||
|
|
@ -365,27 +355,25 @@ impl Application for App {
|
||||||
self.workspaces.push(Workspace {
|
self.workspaces.push(Workspace {
|
||||||
name: workspace.name,
|
name: workspace.name,
|
||||||
handle: workspace.handle,
|
handle: workspace.handle,
|
||||||
output_names,
|
outputs,
|
||||||
img_for_output,
|
img_for_output,
|
||||||
is_active,
|
is_active,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
self.update_capture_filter();
|
self.update_capture_filter();
|
||||||
}
|
}
|
||||||
wayland::Event::NewToplevel(handle, output_names, info) => {
|
wayland::Event::NewToplevel(handle, info) => {
|
||||||
println!("New toplevel: {info:?}");
|
println!("New toplevel: {info:?}");
|
||||||
self.toplevels.push(Toplevel {
|
self.toplevels.push(Toplevel {
|
||||||
handle,
|
handle,
|
||||||
output_names,
|
|
||||||
info,
|
info,
|
||||||
img: None,
|
img: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
wayland::Event::UpdateToplevel(handle, output_names, info) => {
|
wayland::Event::UpdateToplevel(handle, info) => {
|
||||||
if let Some(toplevel) =
|
if let Some(toplevel) =
|
||||||
self.toplevels.iter_mut().find(|x| x.handle == handle)
|
self.toplevels.iter_mut().find(|x| x.handle == handle)
|
||||||
{
|
{
|
||||||
toplevel.output_names = output_names;
|
|
||||||
toplevel.info = info;
|
toplevel.info = info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -443,15 +431,12 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
Msg::StartDrag(size, drag_surface) => {
|
Msg::StartDrag(size, drag_surface) => {
|
||||||
match &drag_surface {
|
match &drag_surface {
|
||||||
DragSurface::Workspace {
|
DragSurface::Workspace { output, name: _ } => {
|
||||||
output_name,
|
|
||||||
name: _,
|
|
||||||
} => {
|
|
||||||
let id = self.next_surface_id();
|
let id = self.next_surface_id();
|
||||||
if let Some((parent_id, _)) = self
|
if let Some((parent_id, _)) = self
|
||||||
.layer_surfaces
|
.layer_surfaces
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_, x)| &x.output_name == output_name)
|
.find(|(_, x)| &x.output == output)
|
||||||
{
|
{
|
||||||
self.drag_surface = Some((id, drag_surface, size));
|
self.drag_surface = Some((id, drag_surface, size));
|
||||||
return start_drag(
|
return start_drag(
|
||||||
|
|
@ -516,9 +501,9 @@ impl Application for App {
|
||||||
if let Some((drag_id, drag_surface, size)) = &self.drag_surface {
|
if let Some((drag_id, drag_surface, size)) = &self.drag_surface {
|
||||||
if drag_id == &id {
|
if drag_id == &id {
|
||||||
match drag_surface {
|
match drag_surface {
|
||||||
DragSurface::Workspace { output_name, name } => {
|
DragSurface::Workspace { output, name } => {
|
||||||
if let Some(workspace) = self.workspaces.iter().find(|x| &x.name == name) {
|
if let Some(workspace) = self.workspaces.iter().find(|x| &x.name == name) {
|
||||||
let item = workspace_item(workspace, &output_name);
|
let item = workspace_item(workspace, &output);
|
||||||
return widget::container(item)
|
return widget::container(item)
|
||||||
.height(iced::Length::Fixed(size.height))
|
.height(iced::Length::Fixed(size.height))
|
||||||
.width(iced::Length::Fixed(size.width))
|
.width(iced::Length::Fixed(size.width))
|
||||||
|
|
@ -542,11 +527,11 @@ fn layer_surface<'a>(app: &'a App, surface: &'a LayerSurface) -> cosmic::Element
|
||||||
workspaces_sidebar(
|
workspaces_sidebar(
|
||||||
app.workspaces
|
app.workspaces
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|i| i.output_names.contains(&surface.output_name)),
|
.filter(|i| i.outputs.contains(&surface.output)),
|
||||||
&surface.output_name
|
&surface.output
|
||||||
),
|
),
|
||||||
toplevel_previews(app.toplevels.iter().filter(|i| {
|
toplevel_previews(app.toplevels.iter().filter(|i| {
|
||||||
if !i.output_names.contains(&surface.output_name) {
|
if !i.info.output.contains(&surface.output) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -569,7 +554,10 @@ fn close_button(on_press: Msg) -> cosmic::Element<'static, Msg> {
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn workspace_item<'a>(workspace: &'a Workspace, output_name: &'a str) -> cosmic::Element<'a, Msg> {
|
fn workspace_item<'a>(
|
||||||
|
workspace: &'a Workspace,
|
||||||
|
output: &wl_output::WlOutput,
|
||||||
|
) -> cosmic::Element<'a, Msg> {
|
||||||
// TODO style
|
// TODO style
|
||||||
let theme = if workspace.is_active {
|
let theme = if workspace.is_active {
|
||||||
cosmic::theme::Button::Suggested
|
cosmic::theme::Button::Suggested
|
||||||
|
|
@ -582,7 +570,7 @@ fn workspace_item<'a>(workspace: &'a Workspace, output_name: &'a str) -> cosmic:
|
||||||
widget::Image::new(
|
widget::Image::new(
|
||||||
workspace
|
workspace
|
||||||
.img_for_output
|
.img_for_output
|
||||||
.get(output_name)
|
.get(output)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_else(|| widget::image::Handle::from_pixels(
|
.unwrap_or_else(|| widget::image::Handle::from_pixels(
|
||||||
1,
|
1,
|
||||||
|
|
@ -601,15 +589,15 @@ fn workspace_item<'a>(workspace: &'a Workspace, output_name: &'a str) -> cosmic:
|
||||||
|
|
||||||
fn workspace_sidebar_entry<'a>(
|
fn workspace_sidebar_entry<'a>(
|
||||||
workspace: &'a Workspace,
|
workspace: &'a Workspace,
|
||||||
output_name: &'a str,
|
output: &'a wl_output::WlOutput,
|
||||||
) -> cosmic::Element<'a, Msg> {
|
) -> cosmic::Element<'a, Msg> {
|
||||||
widget::dnd_source(workspace_item(workspace, output_name))
|
widget::dnd_source(workspace_item(workspace, output))
|
||||||
.on_drag(|size| {
|
.on_drag(|size| {
|
||||||
Msg::StartDrag(
|
Msg::StartDrag(
|
||||||
size,
|
size,
|
||||||
DragSurface::Workspace {
|
DragSurface::Workspace {
|
||||||
name: workspace.name.to_string(),
|
name: workspace.name.to_string(),
|
||||||
output_name: output_name.to_string(),
|
output: output.clone(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
@ -620,12 +608,12 @@ fn workspace_sidebar_entry<'a>(
|
||||||
|
|
||||||
fn workspaces_sidebar<'a>(
|
fn workspaces_sidebar<'a>(
|
||||||
workspaces: impl Iterator<Item = &'a Workspace>,
|
workspaces: impl Iterator<Item = &'a Workspace>,
|
||||||
output_name: &'a str,
|
output: &'a wl_output::WlOutput,
|
||||||
) -> cosmic::Element<'a, Msg> {
|
) -> cosmic::Element<'a, Msg> {
|
||||||
widget::container(
|
widget::container(
|
||||||
widget::dnd_listener(widget::column(
|
widget::dnd_listener(widget::column(
|
||||||
workspaces
|
workspaces
|
||||||
.map(|w| workspace_sidebar_entry(w, output_name))
|
.map(|w| workspace_sidebar_entry(w, output))
|
||||||
.collect(),
|
.collect(),
|
||||||
))
|
))
|
||||||
.on_enter(Msg::DndWorkspaceEnter)
|
.on_enter(Msg::DndWorkspaceEnter)
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ impl std::hash::Hash for CaptureSource {
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct CaptureFilter {
|
pub struct CaptureFilter {
|
||||||
// TODO: Use `WlOutput` when one Wayland connection is used
|
// TODO: Use `WlOutput` when one Wayland connection is used
|
||||||
pub workspaces_on_outputs: Vec<String>,
|
pub workspaces_on_outputs: Vec<wl_output::WlOutput>,
|
||||||
pub toplevels_on_workspaces: Vec<zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1>,
|
pub toplevels_on_workspaces: Vec<zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ use cctk::{
|
||||||
screencopy::ScreencopyState,
|
screencopy::ScreencopyState,
|
||||||
sctk::{
|
sctk::{
|
||||||
self,
|
self,
|
||||||
output::{OutputHandler, OutputState},
|
|
||||||
reexports::calloop_wayland_source::WaylandSource,
|
reexports::calloop_wayland_source::WaylandSource,
|
||||||
registry::{ProvidesRegistryState, RegistryState},
|
registry::{ProvidesRegistryState, RegistryState},
|
||||||
seat::{SeatHandler, SeatState},
|
seat::{SeatHandler, SeatState},
|
||||||
|
|
@ -24,10 +23,9 @@ use cctk::{
|
||||||
toplevel_info::{ToplevelInfo, ToplevelInfoState},
|
toplevel_info::{ToplevelInfo, ToplevelInfoState},
|
||||||
toplevel_management::ToplevelManagerState,
|
toplevel_management::ToplevelManagerState,
|
||||||
wayland_client::{
|
wayland_client::{
|
||||||
backend::ObjectId,
|
|
||||||
globals::registry_queue_init,
|
globals::registry_queue_init,
|
||||||
protocol::{wl_output, wl_seat},
|
protocol::{wl_output, wl_seat},
|
||||||
Connection, Proxy, QueueHandle,
|
Connection, QueueHandle,
|
||||||
},
|
},
|
||||||
workspace::WorkspaceState,
|
workspace::WorkspaceState,
|
||||||
};
|
};
|
||||||
|
|
@ -61,21 +59,18 @@ pub enum Event {
|
||||||
CmdSender(calloop::channel::Sender<Cmd>),
|
CmdSender(calloop::channel::Sender<Cmd>),
|
||||||
ToplevelManager(zcosmic_toplevel_manager_v1::ZcosmicToplevelManagerV1),
|
ToplevelManager(zcosmic_toplevel_manager_v1::ZcosmicToplevelManagerV1),
|
||||||
WorkspaceManager(zcosmic_workspace_manager_v1::ZcosmicWorkspaceManagerV1),
|
WorkspaceManager(zcosmic_workspace_manager_v1::ZcosmicWorkspaceManagerV1),
|
||||||
// XXX Output name rather than `WlOutput`
|
Workspaces(Vec<(HashSet<wl_output::WlOutput>, cctk::workspace::Workspace)>),
|
||||||
Workspaces(Vec<(Vec<String>, cctk::workspace::Workspace)>),
|
|
||||||
WorkspaceCapture(
|
WorkspaceCapture(
|
||||||
zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
|
zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
|
||||||
String,
|
wl_output::WlOutput,
|
||||||
image::Handle,
|
image::Handle,
|
||||||
),
|
),
|
||||||
NewToplevel(
|
NewToplevel(
|
||||||
zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||||
HashSet<String>,
|
|
||||||
ToplevelInfo,
|
ToplevelInfo,
|
||||||
),
|
),
|
||||||
UpdateToplevel(
|
UpdateToplevel(
|
||||||
zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||||
HashSet<String>,
|
|
||||||
ToplevelInfo,
|
ToplevelInfo,
|
||||||
),
|
),
|
||||||
CloseToplevel(zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1),
|
CloseToplevel(zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1),
|
||||||
|
|
@ -97,7 +92,6 @@ pub enum Cmd {
|
||||||
|
|
||||||
pub struct AppData {
|
pub struct AppData {
|
||||||
qh: QueueHandle<Self>,
|
qh: QueueHandle<Self>,
|
||||||
output_state: OutputState,
|
|
||||||
registry_state: RegistryState,
|
registry_state: RegistryState,
|
||||||
toplevel_info_state: ToplevelInfoState,
|
toplevel_info_state: ToplevelInfoState,
|
||||||
workspace_state: WorkspaceState,
|
workspace_state: WorkspaceState,
|
||||||
|
|
@ -106,7 +100,6 @@ pub struct AppData {
|
||||||
shm_state: Shm,
|
shm_state: Shm,
|
||||||
toplevel_manager_state: ToplevelManagerState,
|
toplevel_manager_state: ToplevelManagerState,
|
||||||
sender: mpsc::Sender<Event>,
|
sender: mpsc::Sender<Event>,
|
||||||
output_names: HashMap<ObjectId, Option<String>>,
|
|
||||||
seats: Vec<wl_seat::WlSeat>,
|
seats: Vec<wl_seat::WlSeat>,
|
||||||
capture_filter: CaptureFilter,
|
capture_filter: CaptureFilter,
|
||||||
captures: RefCell<HashMap<CaptureSource, Arc<Capture>>>,
|
captures: RefCell<HashMap<CaptureSource, Arc<Capture>>>,
|
||||||
|
|
@ -138,11 +131,7 @@ impl AppData {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
CaptureSource::Workspace(_, output) => {
|
CaptureSource::Workspace(_, output) => {
|
||||||
if let Some(name) = &self.output_state.info(&output).and_then(|x| x.name) {
|
self.capture_filter.workspaces_on_outputs.contains(output)
|
||||||
self.capture_filter.workspaces_on_outputs.contains(name)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +174,7 @@ impl ProvidesRegistryState for AppData {
|
||||||
&mut self.registry_state
|
&mut self.registry_state
|
||||||
}
|
}
|
||||||
|
|
||||||
sctk::registry_handlers!(OutputState, SeatState);
|
sctk::registry_handlers!(SeatState);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SeatHandler for AppData {
|
impl SeatHandler for AppData {
|
||||||
|
|
@ -229,40 +218,6 @@ impl ShmHandler for AppData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: don't need this if we use same connection with same IDs? Or?
|
|
||||||
impl OutputHandler for AppData {
|
|
||||||
fn output_state(&mut self) -> &mut OutputState {
|
|
||||||
&mut self.output_state
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_output(
|
|
||||||
&mut self,
|
|
||||||
_conn: &Connection,
|
|
||||||
_qh: &QueueHandle<Self>,
|
|
||||||
output: wl_output::WlOutput,
|
|
||||||
) {
|
|
||||||
let name = self.output_state.info(&output).unwrap().name;
|
|
||||||
self.output_names.insert(output.id(), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_output(
|
|
||||||
&mut self,
|
|
||||||
_conn: &Connection,
|
|
||||||
_qh: &QueueHandle<Self>,
|
|
||||||
_output: wl_output::WlOutput,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
fn output_destroyed(
|
|
||||||
&mut self,
|
|
||||||
_conn: &Connection,
|
|
||||||
_qh: &QueueHandle<Self>,
|
|
||||||
output: wl_output::WlOutput,
|
|
||||||
) {
|
|
||||||
self.output_names.remove(&output.id());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start(conn: Connection) -> mpsc::Receiver<Event> {
|
fn start(conn: Connection) -> mpsc::Receiver<Event> {
|
||||||
let (sender, receiver) = mpsc::channel(20);
|
let (sender, receiver) = mpsc::channel(20);
|
||||||
|
|
||||||
|
|
@ -272,7 +227,6 @@ fn start(conn: Connection) -> mpsc::Receiver<Event> {
|
||||||
let registry_state = RegistryState::new(&globals);
|
let registry_state = RegistryState::new(&globals);
|
||||||
let mut app_data = AppData {
|
let mut app_data = AppData {
|
||||||
qh: qh.clone(),
|
qh: qh.clone(),
|
||||||
output_state: OutputState::new(&globals, &qh),
|
|
||||||
workspace_state: WorkspaceState::new(®istry_state, &qh), // Create before toplevel info state
|
workspace_state: WorkspaceState::new(®istry_state, &qh), // Create before toplevel info state
|
||||||
toplevel_info_state: ToplevelInfoState::new(®istry_state, &qh),
|
toplevel_info_state: ToplevelInfoState::new(®istry_state, &qh),
|
||||||
toplevel_manager_state: ToplevelManagerState::new(®istry_state, &qh),
|
toplevel_manager_state: ToplevelManagerState::new(®istry_state, &qh),
|
||||||
|
|
@ -281,7 +235,6 @@ fn start(conn: Connection) -> mpsc::Receiver<Event> {
|
||||||
seat_state: SeatState::new(&globals, &qh),
|
seat_state: SeatState::new(&globals, &qh),
|
||||||
shm_state: Shm::bind(&globals, &qh).unwrap(),
|
shm_state: Shm::bind(&globals, &qh).unwrap(),
|
||||||
sender,
|
sender,
|
||||||
output_names: HashMap::new(),
|
|
||||||
seats: Vec::new(),
|
seats: Vec::new(),
|
||||||
capture_filter: CaptureFilter::default(),
|
capture_filter: CaptureFilter::default(),
|
||||||
captures: RefCell::new(HashMap::new()),
|
captures: RefCell::new(HashMap::new()),
|
||||||
|
|
@ -323,7 +276,7 @@ fn start(conn: Connection) -> mpsc::Receiver<Event> {
|
||||||
receiver
|
receiver
|
||||||
}
|
}
|
||||||
|
|
||||||
sctk::delegate_output!(AppData);
|
// Don't bind outputs; use `WlOutput` instances from iced-sctk
|
||||||
sctk::delegate_registry!(AppData);
|
sctk::delegate_registry!(AppData);
|
||||||
sctk::delegate_seat!(AppData);
|
sctk::delegate_seat!(AppData);
|
||||||
sctk::delegate_shm!(AppData);
|
sctk::delegate_shm!(AppData);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use cctk::{
|
use cctk::{
|
||||||
cosmic_protocols::screencopy::v1::client::zcosmic_screencopy_session_v1,
|
cosmic_protocols::screencopy::v1::client::zcosmic_screencopy_session_v1,
|
||||||
screencopy::{BufferInfo, ScreencopyHandler, ScreencopyState},
|
screencopy::{BufferInfo, ScreencopyHandler, ScreencopyState},
|
||||||
wayland_client::{protocol::wl_shm, Connection, Proxy, QueueHandle, WEnum},
|
wayland_client::{protocol::wl_shm, Connection, QueueHandle, WEnum},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{AppData, Buffer, Capture, CaptureSource, Event};
|
use super::{AppData, Buffer, Capture, CaptureSource, Event};
|
||||||
|
|
@ -76,13 +76,11 @@ impl ScreencopyHandler for AppData {
|
||||||
self.send_event(Event::ToplevelCapture(toplevel.clone(), image))
|
self.send_event(Event::ToplevelCapture(toplevel.clone(), image))
|
||||||
}
|
}
|
||||||
CaptureSource::Workspace(workspace, output) => {
|
CaptureSource::Workspace(workspace, output) => {
|
||||||
if let Some(Some(output_name)) = self.output_names.get(&output.id()) {
|
self.send_event(Event::WorkspaceCapture(
|
||||||
self.send_event(Event::WorkspaceCapture(
|
workspace.clone(),
|
||||||
workspace.clone(),
|
output.clone(),
|
||||||
output_name.clone(),
|
image,
|
||||||
image,
|
));
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
session.destroy();
|
session.destroy();
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use cctk::{
|
||||||
},
|
},
|
||||||
toplevel_info::{ToplevelInfoHandler, ToplevelInfoState},
|
toplevel_info::{ToplevelInfoHandler, ToplevelInfoState},
|
||||||
toplevel_management::{ToplevelManagerHandler, ToplevelManagerState},
|
toplevel_management::{ToplevelManagerHandler, ToplevelManagerState},
|
||||||
wayland_client::{Connection, Proxy, QueueHandle, WEnum},
|
wayland_client::{Connection, QueueHandle, WEnum},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{AppData, CaptureSource, Event};
|
use super::{AppData, CaptureSource, Event};
|
||||||
|
|
@ -23,16 +23,7 @@ impl ToplevelInfoHandler for AppData {
|
||||||
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||||
) {
|
) {
|
||||||
let info = self.toplevel_info_state.info(toplevel).unwrap();
|
let info = self.toplevel_info_state.info(toplevel).unwrap();
|
||||||
let output_names = info
|
self.send_event(Event::NewToplevel(toplevel.clone(), info.clone()));
|
||||||
.output
|
|
||||||
.iter()
|
|
||||||
.filter_map(|o| self.output_names.get(&o.id()).cloned()?)
|
|
||||||
.collect();
|
|
||||||
self.send_event(Event::NewToplevel(
|
|
||||||
toplevel.clone(),
|
|
||||||
output_names,
|
|
||||||
info.clone(),
|
|
||||||
));
|
|
||||||
|
|
||||||
self.add_capture_source(CaptureSource::Toplevel(toplevel.clone()));
|
self.add_capture_source(CaptureSource::Toplevel(toplevel.clone()));
|
||||||
}
|
}
|
||||||
|
|
@ -44,16 +35,7 @@ impl ToplevelInfoHandler for AppData {
|
||||||
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||||
) {
|
) {
|
||||||
let info = self.toplevel_info_state.info(toplevel).unwrap();
|
let info = self.toplevel_info_state.info(toplevel).unwrap();
|
||||||
let output_names = info
|
self.send_event(Event::UpdateToplevel(toplevel.clone(), info.clone()));
|
||||||
.output
|
|
||||||
.iter()
|
|
||||||
.filter_map(|o| self.output_names.get(&o.id()).cloned()?)
|
|
||||||
.collect();
|
|
||||||
self.send_event(Event::UpdateToplevel(
|
|
||||||
toplevel.clone(),
|
|
||||||
output_names,
|
|
||||||
info.clone(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toplevel_closed(
|
fn toplevel_closed(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
use cctk::{
|
use cctk::workspace::{WorkspaceHandler, WorkspaceState};
|
||||||
wayland_client::Proxy,
|
|
||||||
workspace::{WorkspaceHandler, WorkspaceState},
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{AppData, CaptureSource, Event};
|
use super::{AppData, CaptureSource, Event};
|
||||||
|
|
||||||
|
|
@ -18,20 +15,13 @@ impl WorkspaceHandler for AppData {
|
||||||
|
|
||||||
for group in self.workspace_state.workspace_groups() {
|
for group in self.workspace_state.workspace_groups() {
|
||||||
for workspace in &group.workspaces {
|
for workspace in &group.workspaces {
|
||||||
let output_names: Vec<_> = group
|
workspaces.push((group.outputs.iter().cloned().collect(), workspace.clone()));
|
||||||
.outputs
|
|
||||||
.iter()
|
|
||||||
.filter_map(|output| self.output_names.get(&output.id()).cloned()?)
|
|
||||||
.collect();
|
|
||||||
if !output_names.is_empty() {
|
|
||||||
workspaces.push((output_names, workspace.clone()));
|
|
||||||
|
|
||||||
for output in &group.outputs {
|
for output in &group.outputs {
|
||||||
self.add_capture_source(CaptureSource::Workspace(
|
self.add_capture_source(CaptureSource::Workspace(
|
||||||
workspace.handle.clone(),
|
workspace.handle.clone(),
|
||||||
output.clone(),
|
output.clone(),
|
||||||
));
|
));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue