Skip to content

Commit

Permalink
chore: reworks
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Brue <ryanbrue@gmail.com>
  • Loading branch information
ryanabx committed Aug 14, 2024
1 parent 0010f9d commit 9ad4522
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 127 deletions.
95 changes: 2 additions & 93 deletions src/app_tray/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,22 @@ use freedesktop_desktop_entry::DesktopEntry;
use iced::Command;

use crate::compositor::{
cosmic_comp::{CosmicWaylandMessage, ToplevelUpdate, WaylandRequest},
WaylandMessage,
cosmic_comp::{CosmicWaylandMessage, ToplevelUpdate, WaylandRequest}, CompositorBackend, WaylandEvent
};

pub mod desktop_entry;

#[derive(Clone, Debug)]
pub struct AppTray<'a> {
pub wayland_sender: Option<Sender<WaylandRequest>>,
pub de_cache: DesktopEntryCache<'a>,
pub active_toplevels: HashMap<String, ApplicationGroup>,
}

impl<'a> Default for AppTray<'a> {
fn default() -> Self {
Self {
wayland_sender: None,
de_cache: DesktopEntryCache::new(),
active_toplevels: HashMap::new(),
active_toplevels: HashMap::new()
}
}
}
Expand All @@ -36,95 +33,7 @@ pub struct ApplicationGroup {
}

impl<'a> AppTray<'a> {
pub fn wayland_event(
&mut self,
event: WaylandMessage,
) -> Option<iced::Command<crate::Message>> {
match event {
WaylandMessage::CosmicComp(evt) => self.cosmic_wayland_event(evt),
_ => panic!("Not supported"),
}
}

pub fn get_desktop_entry(&mut self, app_id: &str) -> Option<DesktopEntry<'a>> {
self.de_cache.0.get(app_id).cloned()
}

fn cosmic_wayland_event(
&mut self,
event: CosmicWaylandMessage,
) -> Option<iced::Command<crate::Message>> {
match event {
CosmicWaylandMessage::Init(wayland_sender) => {
self.wayland_sender.replace(wayland_sender);
None
}
CosmicWaylandMessage::Finished => {
println!("WHY?");
None
}
CosmicWaylandMessage::Toplevel(toplevel_update) => match toplevel_update {
ToplevelUpdate::Add(handle, info) => {
let app_id = info.app_id.clone();
println!("Adding toplevel with app_id {} to list!", &app_id);
if self.active_toplevels.contains_key(&app_id) {
self.active_toplevels
.get_mut(&info.app_id)
.unwrap()
.toplevels
.insert(handle, info);
} else {
self.active_toplevels.insert(
app_id.clone(),
ApplicationGroup {
toplevels: HashMap::from([(handle, info.clone())]),
},
);
}
None
}
ToplevelUpdate::Update(handle, info) => {
// TODO probably want to make sure it is removed
if info.app_id.is_empty() {
self.active_toplevels.remove(&info.app_id);
return Some(Command::none());
} else if !self.active_toplevels.contains_key(&info.app_id) {
return Some(Command::none());
}

for (t_handle, t_info) in &mut self
.active_toplevels
.get_mut(&info.app_id)
.unwrap()
.toplevels
{
if &handle == t_handle {
*t_info = info;
break;
}
}

None
}
ToplevelUpdate::Remove(handle) => {
let mut target_app_id: Option<String> = None;
for (app_id, app_info) in self.active_toplevels.iter_mut() {
if app_info.toplevels.contains_key(&handle) {
println!("Removing toplevel with app_id {} from list!", &app_id);
app_info.toplevels.remove(&handle);
if app_info.toplevels.is_empty() {
target_app_id = Some(app_id.clone());
}
break;
}
}
if let Some(app_id) = target_app_id {
self.active_toplevels.remove(&app_id);
}
None
}
},
_ => None,
}
}
}
133 changes: 116 additions & 17 deletions src/compositor/cosmic_comp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use std::os::{
fd::{FromRawFd, RawFd},
unix::net::UnixStream,
use std::{
collections::HashMap,
os::{
fd::{FromRawFd, RawFd},
unix::net::UnixStream,
},
};

use cctk::{
Expand All @@ -9,7 +12,7 @@ use cctk::{
output::{OutputHandler, OutputInfo, OutputState},
reexports::{
calloop::{
channel::{self, Channel},
channel::{self, Channel, Sender},
EventLoop,
},
calloop_wayland_source::WaylandSource,
Expand Down Expand Up @@ -40,6 +43,8 @@ use iced::{
};
use once_cell::sync::Lazy;

use super::CompositorBackend;

struct WaylandData {
_conn: Connection,
queue_handle: QueueHandle<Self>,
Expand Down Expand Up @@ -458,19 +463,6 @@ pub enum State {
Finished,
}

pub fn wayland_subscription() -> iced::Subscription<CosmicWaylandMessage> {
subscription::channel(
std::any::TypeId::of::<CosmicWaylandMessage>(),
50,
move |mut output| async move {
let mut state = State::Waiting;

loop {
state = start_listening(state, &mut output).await;
}
},
)
}

pub static WAYLAND_RX: Lazy<Mutex<Option<UnboundedReceiver<CosmicWaylandMessage>>>> =
Lazy::new(|| Mutex::new(None));
Expand Down Expand Up @@ -508,3 +500,110 @@ async fn start_listening(
State::Finished => iced::futures::future::pending().await,
}
}

#[derive(Debug, Clone)]
pub struct CosmicCompBackend {
wayland_sender: Option<Sender<WaylandRequest>>,
}

impl CosmicCompBackend {
pub fn new() -> Self {
Self {
wayland_sender: None
}
}

pub fn wayland_subscription(&self) -> iced::Subscription<CosmicWaylandMessage> {
subscription::channel(
std::any::TypeId::of::<CosmicWaylandMessage>(),
50,
move |mut output| async move {
let mut state = State::Waiting;

loop {
state = start_listening(state, &mut output).await;
}
},
)
}

pub fn handle_message(
&mut self,
app_tray: &mut crate::app_tray::AppTray,
event: CosmicWaylandMessage,
) -> Option<iced::Command<crate::Message>> {
match event {
CosmicWaylandMessage::Init(wayland_sender) => {
self.wayland_sender.replace(wayland_sender);
None
}
CosmicWaylandMessage::Finished => {
println!("WHY?");
None
}
CosmicWaylandMessage::Toplevel(toplevel_update) => match toplevel_update {
ToplevelUpdate::Add(handle, info) => {
let app_id = info.app_id.clone();
println!("Adding toplevel with app_id {} to list!", &app_id);
if app_tray.active_toplevels.contains_key(&app_id) {
app_tray
.active_toplevels
.get_mut(&info.app_id)
.unwrap()
.toplevels
.insert(handle, info);
} else {
app_tray.active_toplevels.insert(
app_id.clone(),
crate::app_tray::ApplicationGroup {
toplevels: HashMap::from([(handle, info.clone())]),
},
);
}
None
}
ToplevelUpdate::Update(handle, info) => {
// TODO probably want to make sure it is removed
if info.app_id.is_empty() {
app_tray.active_toplevels.remove(&info.app_id);
return Some(iced::Command::none());
} else if !app_tray.active_toplevels.contains_key(&info.app_id) {
return Some(iced::Command::none());
}

for (t_handle, t_info) in &mut app_tray
.active_toplevels
.get_mut(&info.app_id)
.unwrap()
.toplevels
{
if &handle == t_handle {
*t_info = info;
break;
}
}

None
}
ToplevelUpdate::Remove(handle) => {
let mut target_app_id: Option<String> = None;
for (app_id, app_info) in app_tray.active_toplevels.iter_mut() {
if app_info.toplevels.contains_key(&handle) {
println!("Removing toplevel with app_id {} from list!", &app_id);
app_info.toplevels.remove(&handle);
if app_info.toplevels.is_empty() {
target_app_id = Some(app_id.clone());
}
break;
}
}
if let Some(app_id) = target_app_id {
app_tray.active_toplevels.remove(&app_id);
}
None
}
},
_ => None,
}
}
}
58 changes: 46 additions & 12 deletions src/compositor/mod.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,56 @@
use std::env;

use cosmic_comp::CosmicCompBackend;
use cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1;

use crate::app_tray::AppTray;

pub mod cosmic_comp;
pub mod wlr;

#[derive(Clone, Debug)]
pub enum WaylandMessage {
CosmicComp(cosmic_comp::CosmicWaylandMessage),
Wlroots(),
pub enum CompositorBackend {
Cosmic(CosmicCompBackend),
}

pub(crate) fn wayland_subscription() -> iced::Subscription<WaylandMessage> {
// set the environment variable RYANABX_SHELL_DESKTOP to set which desktop session should be inferred
let current_compositor = match env::var("RYANABX_SHELL_DESKTOP") {
Ok(val) => Ok(val),
_ => env::var("XDG_CURRENT_DESKTOP"), // fall back on XDG_CURRENT_DESKTOP if not set
};
match current_compositor.as_deref() {
Ok("COSMIC") => cosmic_comp::wayland_subscription().map(WaylandMessage::CosmicComp),
_ => panic!("Unsupported desktop"),
impl CompositorBackend {
pub fn new() -> Self {
// set the environment variable RYANABX_SHELL_DESKTOP to set which desktop session should be inferred
let current_compositor = match env::var("RYANABX_SHELL_DESKTOP") {
Ok(val) => Ok(val),
_ => env::var("XDG_CURRENT_DESKTOP"), // fall back on XDG_CURRENT_DESKTOP if not set
};
match current_compositor.as_deref() {
Ok("COSMIC") => Self::Cosmic(CosmicCompBackend::new()),
_ => panic!("Unsupported desktop"),
}
}

pub fn wayland_subscription(&self) -> iced::Subscription<WaylandEvent> {
match self {
Self::Cosmic(backend) => backend.wayland_subscription().map(WaylandEvent::Cosmic),
}
}

pub fn handle_message(
&mut self,
app_tray: &mut AppTray,
event: WaylandEvent,
) -> Option<iced::Command<crate::Message>> {
match (self, event) {
(Self::Cosmic(backend), WaylandEvent::Cosmic(evt)) => {
backend.handle_message(app_tray, evt)
}
}
}
}

#[derive(Clone, Debug)]
pub enum WaylandEvent {
Cosmic(cosmic_comp::CosmicWaylandMessage),
}

#[derive(Clone, Debug)]
pub enum WindowHandle {
Cosmic(ZcosmicToplevelHandleV1),
}
Loading

0 comments on commit 9ad4522

Please sign in to comment.