Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Massive Client Refactor #396

Merged
merged 3 commits into from
Jan 9, 2024
Merged
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
165 changes: 85 additions & 80 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 3 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ clock = ["chrono"]
music = ["regex"]
"music+all" = ["music", "music+mpris", "music+mpd"]
"music+mpris" = ["music", "mpris"]
"music+mpd" = ["music", "mpd_client"]
"music+mpd" = ["music", "mpd-utils"]

sys_info = ["sysinfo", "regex"]

Expand Down Expand Up @@ -94,9 +94,6 @@ smithay-client-toolkit = { version = "0.18.0", default-features = false, feature
] }
universal-config = { version = "0.4.3", default_features = false }
ctrlc = "3.4.2"

lazy_static = "1.4.0"
async_once = "0.2.6"
cfg-if = "1.0.0"

# cli
Expand All @@ -115,7 +112,7 @@ nix = { version = "0.27.1", optional = true, features = ["event"] }
chrono = { version = "0.4.31", optional = true, features = ["unstable-locales"] }

# music
mpd_client = { version = "1.3.0", optional = true }
mpd-utils = { version = "0.2.0", optional = true }
mpris = { version = "2.0.1", optional = true }

# sys_info
Expand All @@ -126,7 +123,7 @@ system-tray = { version = "0.1.4", optional = true }

# upower
upower_dbus = { version = "0.3.2", optional = true }
futures-lite = { version = "2.1.0", optional = true }
futures-lite = { version = "2.2.0", optional = true }
zbus = { version = "3.14.1", optional = true }

# workspaces
Expand Down
21 changes: 16 additions & 5 deletions src/bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub struct Bar {
monitor_name: String,
position: BarPosition,

ironbar: Rc<Ironbar>,

window: ApplicationWindow,

content: gtk::Box,
Expand All @@ -39,7 +41,12 @@ pub struct Bar {
}

impl Bar {
pub fn new(app: &Application, monitor_name: String, config: Config) -> Self {
pub fn new(
app: &Application,
monitor_name: String,
config: Config,
ironbar: Rc<Ironbar>,
) -> Self {
let window = ApplicationWindow::builder()
.application(app)
.type_(WindowType::Toplevel)
Expand Down Expand Up @@ -90,6 +97,7 @@ impl Bar {
name,
monitor_name,
position,
ironbar,
window,
content,
start,
Expand Down Expand Up @@ -263,17 +271,17 @@ impl Bar {

if let Some(modules) = config.start {
let info = info!(ModuleLocation::Left);
add_modules(&self.start, modules, &info, &popup)?;
add_modules(&self.start, modules, &info, &self.ironbar, &popup)?;
}

if let Some(modules) = config.center {
let info = info!(ModuleLocation::Center);
add_modules(&self.center, modules, &info, &popup)?;
add_modules(&self.center, modules, &info, &self.ironbar, &popup)?;
}

if let Some(modules) = config.end {
let info = info!(ModuleLocation::Right);
add_modules(&self.end, modules, &info, &popup)?;
add_modules(&self.end, modules, &info, &self.ironbar, &popup)?;
}

let result = BarLoadResult { popup };
Expand Down Expand Up @@ -333,6 +341,7 @@ fn add_modules(
content: &gtk::Box,
modules: Vec<ModuleConfig>,
info: &ModuleInfo,
ironbar: &Rc<Ironbar>,
popup: &Rc<RefCell<Popup>>,
) -> Result<()> {
let orientation = info.bar_position.get_orientation();
Expand All @@ -343,6 +352,7 @@ fn add_modules(
let widget_parts = create_module(
*$module,
$id,
ironbar.clone(),
common.name.clone(),
&info,
&Rc::clone(&popup),
Expand Down Expand Up @@ -387,7 +397,8 @@ pub fn create_bar(
monitor: &Monitor,
monitor_name: String,
config: Config,
ironbar: Rc<Ironbar>,
) -> Result<Bar> {
let bar = Bar::new(app, monitor_name, config);
let bar = Bar::new(app, monitor_name, config, ironbar);
bar.init(monitor)
}
50 changes: 23 additions & 27 deletions src/clients/clipboard.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use super::wayland::{self, ClipboardItem};
use crate::{arc_mut, lock, spawn, try_send};
use crate::{arc_mut, lock, register_client, spawn, try_send};
use indexmap::map::Iter;
use indexmap::IndexMap;
use lazy_static::lazy_static;
use std::sync::{Arc, Mutex};
use tokio::sync::mpsc;
use tracing::{debug, trace};

#[derive(Debug)]
pub enum ClipboardEvent {
Add(Arc<ClipboardItem>),
Add(ClipboardItem),
Remove(usize),
Activate(usize),
}
Expand All @@ -18,13 +17,16 @@ type EventSender = mpsc::Sender<ClipboardEvent>;

/// Clipboard client singleton,
/// to ensure bars don't duplicate requests to the compositor.
pub struct ClipboardClient {
#[derive(Debug)]
pub struct Client {
wayland: Arc<wayland::Client>,

senders: Arc<Mutex<Vec<(EventSender, usize)>>>,
cache: Arc<Mutex<ClipboardCache>>,
}

impl ClipboardClient {
fn new() -> Self {
impl Client {
pub(crate) fn new(wl: Arc<wayland::Client>) -> Self {
trace!("Initializing clipboard client");

let senders = arc_mut!(Vec::<(EventSender, usize)>::new());
Expand All @@ -34,13 +36,11 @@ impl ClipboardClient {
{
let senders = senders.clone();
let cache = cache.clone();
let wl = wl.clone();

spawn(async move {
let (mut rx, item) = {
let wl = wayland::get_client();
let wl = lock!(wl);
wl.subscribe_clipboard()
};
let item = wl.clipboard_item();
let mut rx = wl.subscribe_clipboard();

if let Some(item) = item {
let senders = lock!(senders);
Expand Down Expand Up @@ -91,7 +91,11 @@ impl ClipboardClient {
});
}

Self { senders, cache }
Self {
wayland: wl,
senders,
cache,
}
}

pub fn subscribe(&self, cache_size: usize) -> mpsc::Receiver<ClipboardEvent> {
Expand Down Expand Up @@ -120,9 +124,7 @@ impl ClipboardClient {
};

if let Some(item) = item {
let wl = wayland::get_client();
let wl = lock!(wl);
wl.copy_to_clipboard(item);
self.wayland.copy_to_clipboard(item);
}

let senders = lock!(self.senders);
Expand Down Expand Up @@ -150,7 +152,7 @@ impl ClipboardClient {
/// at different times.
#[derive(Debug)]
struct ClipboardCache {
cache: IndexMap<usize, (Arc<ClipboardItem>, usize)>,
cache: IndexMap<usize, (ClipboardItem, usize)>,
}

impl ClipboardCache {
Expand All @@ -162,20 +164,20 @@ impl ClipboardCache {
}

/// Gets the entry with key `id` from the cache.
fn get(&self, id: usize) -> Option<Arc<ClipboardItem>> {
fn get(&self, id: usize) -> Option<ClipboardItem> {
self.cache.get(&id).map(|(item, _)| item).cloned()
}

/// Inserts an entry with `ref_count` initial references.
fn insert(&mut self, item: Arc<ClipboardItem>, ref_count: usize) -> Option<Arc<ClipboardItem>> {
fn insert(&mut self, item: ClipboardItem, ref_count: usize) -> Option<ClipboardItem> {
self.cache
.insert(item.id, (item, ref_count))
.map(|(item, _)| item)
}

/// Removes the entry with key `id`.
/// This ignores references.
fn remove(&mut self, id: usize) -> Option<Arc<ClipboardItem>> {
fn remove(&mut self, id: usize) -> Option<ClipboardItem> {
self.cache.shift_remove(&id).map(|(item, _)| item)
}

Expand Down Expand Up @@ -224,15 +226,9 @@ impl ClipboardCache {
self.cache.len()
}

fn iter(&self) -> Iter<'_, usize, (Arc<ClipboardItem>, usize)> {
fn iter(&self) -> Iter<'_, usize, (ClipboardItem, usize)> {
self.cache.iter()
}
}

lazy_static! {
static ref CLIENT: ClipboardClient = ClipboardClient::new();
}

pub fn get_client() -> &'static ClipboardClient {
&CLIENT
}
register_client!(Client, clipboard);
29 changes: 10 additions & 19 deletions src/clients/compositor/hyprland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,26 @@ use hyprland::dispatch::{Dispatch, DispatchType, WorkspaceIdentifierWithSpecial}
use hyprland::event_listener::EventListener;
use hyprland::prelude::*;
use hyprland::shared::{HyprDataVec, WorkspaceType};
use lazy_static::lazy_static;
use tokio::sync::broadcast::{channel, Receiver, Sender};
use tracing::{debug, error, info};

pub struct EventClient {
#[derive(Debug)]
pub struct Client {
workspace_tx: Sender<WorkspaceUpdate>,
_workspace_rx: Receiver<WorkspaceUpdate>,
}

impl EventClient {
fn new() -> Self {
impl Client {
pub(crate) fn new() -> Self {
let (workspace_tx, workspace_rx) = channel(16);

Self {
let instance = Self {
workspace_tx,
_workspace_rx: workspace_rx,
}
};

instance.listen_workspace_events();
instance
}

fn listen_workspace_events(&self) {
Expand Down Expand Up @@ -203,7 +206,7 @@ impl EventClient {
}
}

impl WorkspaceClient for EventClient {
impl WorkspaceClient for Client {
fn focus(&self, id: String) -> Result<()> {
let identifier = match id.parse::<i32>() {
Ok(inum) => WorkspaceIdentifierWithSpecial::Id(inum),
Expand Down Expand Up @@ -239,18 +242,6 @@ impl WorkspaceClient for EventClient {
}
}

lazy_static! {
static ref CLIENT: EventClient = {
let client = EventClient::new();
client.listen_workspace_events();
client
};
}

pub fn get_client() -> &'static EventClient {
&CLIENT
}

fn get_workspace_name(name: WorkspaceType) -> String {
match name {
WorkspaceType::Regular(name) => name,
Expand Down
20 changes: 13 additions & 7 deletions src/clients/compositor/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{await_sync, register_client};
use cfg_if::cfg_if;
use color_eyre::{Help, Report, Result};
use std::fmt::{Display, Formatter};
use std::fmt::{Debug, Display, Formatter};
use std::sync::Arc;
use tokio::sync::broadcast;
use tracing::debug;

Expand Down Expand Up @@ -44,23 +46,25 @@ impl Compositor {
}
} else if std::env::var("HYPRLAND_INSTANCE_SIGNATURE").is_ok() {
cfg_if! {
if #[cfg(feature = "workspaces+hyprland")] { Self::Hyprland}
if #[cfg(feature = "workspaces+hyprland")] { Self::Hyprland }
else { tracing::error!("Not compiled with Hyprland support"); Self::Unsupported }
}
} else {
Self::Unsupported
}
}

/// Gets the workspace client for the current compositor
pub fn get_workspace_client() -> Result<&'static (dyn WorkspaceClient + Send)> {
/// Creates a new instance of
/// the workspace client for the current compositor.
pub fn create_workspace_client() -> Result<Arc<dyn WorkspaceClient + Send + Sync>> {
let current = Self::get_current();
debug!("Getting workspace client for: {current}");
match current {
#[cfg(feature = "workspaces+sway")]
Self::Sway => Ok(sway::get_sub_client()),
Self::Sway => await_sync(async { sway::Client::new().await })
.map(|client| Arc::new(client) as Arc<dyn WorkspaceClient + Send + Sync>),
#[cfg(feature = "workspaces+hyprland")]
Self::Hyprland => Ok(hyprland::get_client()),
Self::Hyprland => Ok(Arc::new(hyprland::Client::new())),
Self::Unsupported => Err(Report::msg("Unsupported compositor")
.note("Currently workspaces are only supported by Sway and Hyprland")),
}
Expand Down Expand Up @@ -129,10 +133,12 @@ pub enum WorkspaceUpdate {
Unknown,
}

pub trait WorkspaceClient {
pub trait WorkspaceClient: Debug + Send + Sync {
/// Requests the workspace with this name is focused.
fn focus(&self, name: String) -> Result<()>;

/// Creates a new to workspace event receiver.
fn subscribe_workspace_change(&self) -> broadcast::Receiver<WorkspaceUpdate>;
}

register_client!(dyn WorkspaceClient, workspaces);
Loading
Loading