Use Cmd instead of sending more wayland objects to frontend
This isn't needed now that the workspaces view is persistent (before, it was necessary to make sure activation requests are flushed before closing). This is easier to spoof, for testing.
This commit is contained in:
parent
8365efb30d
commit
170e102275
2 changed files with 65 additions and 69 deletions
81
src/main.rs
81
src/main.rs
|
|
@ -6,14 +6,13 @@
|
||||||
use cctk::{
|
use cctk::{
|
||||||
cosmic_protocols::{
|
cosmic_protocols::{
|
||||||
toplevel_info::v1::client::zcosmic_toplevel_handle_v1,
|
toplevel_info::v1::client::zcosmic_toplevel_handle_v1,
|
||||||
toplevel_management::v1::client::zcosmic_toplevel_manager_v1,
|
workspace::v1::client::zcosmic_workspace_handle_v1,
|
||||||
workspace::v1::client::{zcosmic_workspace_handle_v1, zcosmic_workspace_manager_v1},
|
|
||||||
},
|
},
|
||||||
sctk::shell::wlr_layer::{Anchor, KeyboardInteractivity, Layer},
|
sctk::shell::wlr_layer::{Anchor, KeyboardInteractivity, Layer},
|
||||||
toplevel_info::ToplevelInfo,
|
toplevel_info::ToplevelInfo,
|
||||||
wayland_client::{
|
wayland_client::{
|
||||||
backend::ObjectId,
|
backend::ObjectId,
|
||||||
protocol::{wl_data_device_manager::DndAction, wl_output, wl_seat},
|
protocol::{wl_data_device_manager::DndAction, wl_output},
|
||||||
Connection, Proxy, WEnum,
|
Connection, Proxy, WEnum,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -202,9 +201,6 @@ struct App {
|
||||||
workspaces: Vec<Workspace>,
|
workspaces: Vec<Workspace>,
|
||||||
toplevels: Vec<Toplevel>,
|
toplevels: Vec<Toplevel>,
|
||||||
conn: Option<Connection>,
|
conn: Option<Connection>,
|
||||||
workspace_manager: Option<zcosmic_workspace_manager_v1::ZcosmicWorkspaceManagerV1>,
|
|
||||||
toplevel_manager: Option<zcosmic_toplevel_manager_v1::ZcosmicToplevelManagerV1>,
|
|
||||||
seats: Vec<wl_seat::WlSeat>,
|
|
||||||
visible: bool,
|
visible: bool,
|
||||||
wayland_cmd_sender: Option<calloop::channel::Sender<wayland::Cmd>>,
|
wayland_cmd_sender: Option<calloop::channel::Sender<wayland::Cmd>>,
|
||||||
drag_surface: Option<(SurfaceId, DragSurface, Size)>,
|
drag_surface: Option<(SurfaceId, DragSurface, Size)>,
|
||||||
|
|
@ -315,22 +311,26 @@ impl App {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_capture_filter(&self) {
|
fn send_wayland_cmd(&self, cmd: wayland::Cmd) {
|
||||||
if let Some(sender) = self.wayland_cmd_sender.as_ref() {
|
if let Some(sender) = self.wayland_cmd_sender.as_ref() {
|
||||||
let mut capture_filter = wayland::CaptureFilter::default();
|
sender.send(cmd).unwrap();
|
||||||
if self.visible {
|
|
||||||
capture_filter.workspaces_on_outputs =
|
|
||||||
self.outputs.iter().map(|x| x.handle.clone()).collect();
|
|
||||||
capture_filter.toplevels_on_workspaces = self
|
|
||||||
.workspaces
|
|
||||||
.iter()
|
|
||||||
.filter(|x| x.is_active)
|
|
||||||
.map(|x| x.handle.clone())
|
|
||||||
.collect();
|
|
||||||
}
|
|
||||||
let _ = sender.send(wayland::Cmd::CaptureFilter(capture_filter));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_capture_filter(&self) {
|
||||||
|
let mut capture_filter = wayland::CaptureFilter::default();
|
||||||
|
if self.visible {
|
||||||
|
capture_filter.workspaces_on_outputs =
|
||||||
|
self.outputs.iter().map(|x| x.handle.clone()).collect();
|
||||||
|
capture_filter.toplevels_on_workspaces = self
|
||||||
|
.workspaces
|
||||||
|
.iter()
|
||||||
|
.filter(|x| x.is_active)
|
||||||
|
.map(|x| x.handle.clone())
|
||||||
|
.collect();
|
||||||
|
}
|
||||||
|
self.send_wayland_cmd(wayland::Cmd::CaptureFilter(capture_filter));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Application for App {
|
impl Application for App {
|
||||||
|
|
@ -416,12 +416,6 @@ impl Application for App {
|
||||||
wayland::Event::CmdSender(sender) => {
|
wayland::Event::CmdSender(sender) => {
|
||||||
self.wayland_cmd_sender = Some(sender);
|
self.wayland_cmd_sender = Some(sender);
|
||||||
}
|
}
|
||||||
wayland::Event::ToplevelManager(manager) => {
|
|
||||||
self.toplevel_manager = Some(manager);
|
|
||||||
}
|
|
||||||
wayland::Event::WorkspaceManager(manager) => {
|
|
||||||
self.workspace_manager = Some(manager);
|
|
||||||
}
|
|
||||||
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();
|
||||||
|
|
@ -480,30 +474,17 @@ impl Application for App {
|
||||||
toplevel.img = Some(image);
|
toplevel.img = Some(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wayland::Event::Seats(seats) => {
|
|
||||||
self.seats = seats;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Msg::Close => {
|
Msg::Close => {
|
||||||
return self.hide();
|
return self.hide();
|
||||||
}
|
}
|
||||||
Msg::ActivateWorkspace(workspace_handle) => {
|
Msg::ActivateWorkspace(workspace_handle) => {
|
||||||
let workspace_manager = self.workspace_manager.as_ref().unwrap();
|
self.send_wayland_cmd(wayland::Cmd::ActivateWorkspace(workspace_handle));
|
||||||
workspace_handle.activate();
|
|
||||||
workspace_manager.commit();
|
|
||||||
let _ = self.conn.as_ref().unwrap().flush();
|
|
||||||
}
|
}
|
||||||
Msg::ActivateToplevel(toplevel_handle) => {
|
Msg::ActivateToplevel(toplevel_handle) => {
|
||||||
if let Some(toplevel_manager) = self.toplevel_manager.as_ref() {
|
self.send_wayland_cmd(wayland::Cmd::ActivateToplevel(toplevel_handle));
|
||||||
if !self.seats.is_empty() {
|
return self.hide();
|
||||||
for seat in &self.seats {
|
|
||||||
toplevel_manager.activate(&toplevel_handle, seat);
|
|
||||||
}
|
|
||||||
let _ = self.conn.as_ref().unwrap().flush();
|
|
||||||
return self.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Msg::CloseWorkspace(_workspace_handle) => {
|
Msg::CloseWorkspace(_workspace_handle) => {
|
||||||
// XXX close specific workspace
|
// XXX close specific workspace
|
||||||
|
|
@ -521,9 +502,7 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
Msg::CloseToplevel(toplevel_handle) => {
|
Msg::CloseToplevel(toplevel_handle) => {
|
||||||
// TODO confirmation?
|
// TODO confirmation?
|
||||||
if let Some(toplevel_manager) = self.toplevel_manager.as_ref() {
|
self.send_wayland_cmd(wayland::Cmd::CloseToplevel(toplevel_handle));
|
||||||
toplevel_manager.close(&toplevel_handle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Msg::StartDrag(size, drag_surface) => {
|
Msg::StartDrag(size, drag_surface) => {
|
||||||
let (wl_id, output, mime_type) = match &drag_surface {
|
let (wl_id, output, mime_type) = match &drag_surface {
|
||||||
|
|
@ -580,15 +559,11 @@ impl Application for App {
|
||||||
.and_then(|s| u32::from_str(s).ok());
|
.and_then(|s| u32::from_str(s).ok());
|
||||||
if let Some((_, DragSurface::Toplevel { handle, .. }, _)) = &self.drag_surface {
|
if let Some((_, DragSurface::Toplevel { handle, .. }, _)) = &self.drag_surface {
|
||||||
if let Some(drop_target) = &self.drop_target {
|
if let Some(drop_target) = &self.drop_target {
|
||||||
if let Some(toplevel_manager) = self.toplevel_manager.as_ref() {
|
self.send_wayland_cmd(wayland::Cmd::MoveToplevelToWorkspace(
|
||||||
if toplevel_manager.version() >= 2 {
|
handle.clone(),
|
||||||
toplevel_manager.move_to_workspace(
|
drop_target.0.clone(),
|
||||||
handle,
|
drop_target.1.clone(),
|
||||||
&drop_target.0,
|
));
|
||||||
&drop_target.1,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ use calloop_wayland_source::WaylandSource;
|
||||||
use cctk::{
|
use cctk::{
|
||||||
cosmic_protocols::{
|
cosmic_protocols::{
|
||||||
toplevel_info::v1::client::zcosmic_toplevel_handle_v1,
|
toplevel_info::v1::client::zcosmic_toplevel_handle_v1,
|
||||||
toplevel_management::v1::client::zcosmic_toplevel_manager_v1,
|
workspace::v1::client::zcosmic_workspace_handle_v1,
|
||||||
workspace::v1::client::{zcosmic_workspace_handle_v1, zcosmic_workspace_manager_v1},
|
|
||||||
},
|
},
|
||||||
screencopy::ScreencopyState,
|
screencopy::ScreencopyState,
|
||||||
sctk::{
|
sctk::{
|
||||||
|
|
@ -21,7 +20,7 @@ use cctk::{
|
||||||
wayland_client::{
|
wayland_client::{
|
||||||
globals::registry_queue_init,
|
globals::registry_queue_init,
|
||||||
protocol::{wl_output, wl_seat},
|
protocol::{wl_output, wl_seat},
|
||||||
Connection, QueueHandle,
|
Connection, Proxy, QueueHandle,
|
||||||
},
|
},
|
||||||
workspace::WorkspaceState,
|
workspace::WorkspaceState,
|
||||||
};
|
};
|
||||||
|
|
@ -58,8 +57,6 @@ pub use capture::CaptureFilter;
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
CmdSender(calloop::channel::Sender<Cmd>),
|
CmdSender(calloop::channel::Sender<Cmd>),
|
||||||
ToplevelManager(zcosmic_toplevel_manager_v1::ZcosmicToplevelManagerV1),
|
|
||||||
WorkspaceManager(zcosmic_workspace_manager_v1::ZcosmicWorkspaceManagerV1),
|
|
||||||
Workspaces(Vec<(HashSet<wl_output::WlOutput>, cctk::workspace::Workspace)>),
|
Workspaces(Vec<(HashSet<wl_output::WlOutput>, cctk::workspace::Workspace)>),
|
||||||
WorkspaceCapture(
|
WorkspaceCapture(
|
||||||
zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
|
zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
|
||||||
|
|
@ -79,7 +76,6 @@ pub enum Event {
|
||||||
zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||||
CaptureImage,
|
CaptureImage,
|
||||||
),
|
),
|
||||||
Seats(Vec<wl_seat::WlSeat>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
@ -98,6 +94,14 @@ pub fn subscription(conn: Connection) -> iced::Subscription<Event> {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Cmd {
|
pub enum Cmd {
|
||||||
CaptureFilter(CaptureFilter),
|
CaptureFilter(CaptureFilter),
|
||||||
|
ActivateToplevel(zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1),
|
||||||
|
CloseToplevel(zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1),
|
||||||
|
MoveToplevelToWorkspace(
|
||||||
|
zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
|
||||||
|
zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
|
||||||
|
wl_output::WlOutput,
|
||||||
|
),
|
||||||
|
ActivateWorkspace(zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AppData {
|
pub struct AppData {
|
||||||
|
|
@ -131,6 +135,33 @@ impl AppData {
|
||||||
self.capture_filter = filter;
|
self.capture_filter = filter;
|
||||||
self.invalidate_capture_filter();
|
self.invalidate_capture_filter();
|
||||||
}
|
}
|
||||||
|
Cmd::ActivateToplevel(toplevel_handle) => {
|
||||||
|
if !self.seats.is_empty() {
|
||||||
|
for seat in &self.seats {
|
||||||
|
self.toplevel_manager_state
|
||||||
|
.manager
|
||||||
|
.activate(&toplevel_handle, seat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Cmd::CloseToplevel(toplevel_handle) => {
|
||||||
|
self.toplevel_manager_state.manager.close(&toplevel_handle);
|
||||||
|
}
|
||||||
|
Cmd::MoveToplevelToWorkspace(toplevel_handle, workspace_handle, output) => {
|
||||||
|
if self.toplevel_manager_state.manager.version() >= 2 {
|
||||||
|
self.toplevel_manager_state.manager.move_to_workspace(
|
||||||
|
&toplevel_handle,
|
||||||
|
&workspace_handle,
|
||||||
|
&output,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Cmd::ActivateWorkspace(workspace_handle) => {
|
||||||
|
if let Ok(workspace_manager) = self.workspace_state.workspace_manager().get() {
|
||||||
|
workspace_handle.activate();
|
||||||
|
workspace_manager.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,14 +228,12 @@ impl SeatHandler for AppData {
|
||||||
|
|
||||||
fn new_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, seat: wl_seat::WlSeat) {
|
fn new_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, seat: wl_seat::WlSeat) {
|
||||||
self.seats.push(seat);
|
self.seats.push(seat);
|
||||||
self.send_event(Event::Seats(self.seats.clone()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, seat: wl_seat::WlSeat) {
|
fn remove_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, seat: wl_seat::WlSeat) {
|
||||||
if let Some(idx) = self.seats.iter().position(|i| i == &seat) {
|
if let Some(idx) = self.seats.iter().position(|i| i == &seat) {
|
||||||
self.seats.remove(idx);
|
self.seats.remove(idx);
|
||||||
}
|
}
|
||||||
self.send_event(Event::Seats(self.seats.clone()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_capability(
|
fn new_capability(
|
||||||
|
|
@ -263,14 +292,6 @@ fn start(conn: Connection) -> mpsc::Receiver<Event> {
|
||||||
scheduler,
|
scheduler,
|
||||||
};
|
};
|
||||||
|
|
||||||
app_data.send_event(Event::Seats(app_data.seat_state.seats().collect()));
|
|
||||||
app_data.send_event(Event::ToplevelManager(
|
|
||||||
app_data.toplevel_manager_state.manager.clone(),
|
|
||||||
));
|
|
||||||
if let Ok(manager) = app_data.workspace_state.workspace_manager().get() {
|
|
||||||
app_data.send_event(Event::WorkspaceManager(manager.clone()));
|
|
||||||
}
|
|
||||||
|
|
||||||
let (cmd_sender, cmd_channel) = calloop::channel::channel();
|
let (cmd_sender, cmd_channel) = calloop::channel::channel();
|
||||||
app_data.send_event(Event::CmdSender(cmd_sender));
|
app_data.send_event(Event::CmdSender(cmd_sender));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue