-
-
Notifications
You must be signed in to change notification settings - Fork 197
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(linux): remove zbus and use unity launcher APIs directly (#880)
* refactor(linux): remove zbus and use unity launcher APIs directly * change files * fmt --------- Co-authored-by: Lucas Nogueira <[email protected]>
- Loading branch information
1 parent
3424f63
commit 2af9131
Showing
8 changed files
with
135 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"tao": minor | ||
--- | ||
|
||
Updated the minimum supported Rust version to 1.70. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"tao": minor | ||
--- | ||
|
||
Progress bar on Linux no longer relies on zbus. Changed `ProgressBarState`'s field `unity_uri` to `desktop_filename`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,138 @@ | ||
use std::ffi::CString; | ||
|
||
use dlopen2::wrapper::{Container, WrapperApi}; | ||
|
||
use crate::window::{ProgressBarState, ProgressState}; | ||
use zbus::{ | ||
blocking::Connection, | ||
fdo::Result, | ||
zvariant::{DeserializeDict, SerializeDict, Type}, | ||
Message, | ||
}; | ||
|
||
pub struct TaskbarIndicator { | ||
conn: Connection, | ||
app_uri: String, | ||
#[derive(WrapperApi)] | ||
struct UnityLib { | ||
unity_launcher_entry_get_for_desktop_id: unsafe extern "C" fn(id: *const i8) -> *const isize, | ||
unity_inspector_get_default: unsafe extern "C" fn() -> *const isize, | ||
unity_inspector_get_unity_running: unsafe extern "C" fn(inspector: *const isize) -> i32, | ||
unity_launcher_entry_set_progress: unsafe extern "C" fn(entry: *const isize, value: f64) -> i32, | ||
unity_launcher_entry_set_progress_visible: | ||
unsafe extern "C" fn(entry: *const isize, value: i32) -> i32, | ||
} | ||
|
||
#[derive(Default, SerializeDict, DeserializeDict, Type, PartialEq, Debug)] | ||
#[zvariant(signature = "dict")] | ||
struct Progress { | ||
progress: Option<f64>, | ||
#[zvariant(rename = "progress-visible")] | ||
progress_visible: Option<bool>, | ||
urgent: Option<bool>, | ||
pub struct TaskbarIndicator { | ||
desktop_filename: Option<String>, | ||
desktop_filename_c_str: Option<CString>, | ||
|
||
is_supported: bool, | ||
unity_lib: Option<Container<UnityLib>>, | ||
attempted_load: bool, | ||
|
||
unity_inspector: Option<*const isize>, | ||
unity_entry: Option<*const isize>, | ||
} | ||
|
||
impl TaskbarIndicator { | ||
pub fn new() -> Result<Self> { | ||
let conn = Connection::session()?; | ||
pub fn new() -> Self { | ||
Self { | ||
desktop_filename: None, | ||
desktop_filename_c_str: None, | ||
|
||
Ok(Self { | ||
conn, | ||
app_uri: String::new(), | ||
}) | ||
is_supported: is_supported(), | ||
unity_lib: None, | ||
attempted_load: false, | ||
|
||
unity_inspector: None, | ||
unity_entry: None, | ||
} | ||
} | ||
|
||
pub fn update(&mut self, progress: ProgressBarState) -> Result<()> { | ||
let mut properties = Progress::default(); | ||
fn ensure_lib_load(&mut self) { | ||
if self.attempted_load { | ||
return; | ||
} | ||
|
||
self.attempted_load = true; | ||
|
||
self.unity_lib = unsafe { | ||
Container::load("libunity.so.4") | ||
.or_else(|_| Container::load("libunity.so.6")) | ||
.or_else(|_| Container::load("libunity.so.9")) | ||
.ok() | ||
}; | ||
|
||
if let Some(uri) = progress.unity_uri { | ||
self.app_uri = uri; | ||
if let Some(unity_lib) = &self.unity_lib { | ||
let handle = unsafe { unity_lib.unity_inspector_get_default() }; | ||
if !handle.is_null() { | ||
self.unity_inspector = Some(handle); | ||
} | ||
} | ||
} | ||
|
||
if let Some(progress) = progress.progress { | ||
let progress = if progress > 100 { 100 } else { progress }; | ||
fn ensure_entry_load(&mut self) { | ||
if let Some(unity_lib) = &self.unity_lib { | ||
if let Some(id) = &self.desktop_filename_c_str { | ||
let handle = unsafe { unity_lib.unity_launcher_entry_get_for_desktop_id(id.as_ptr()) }; | ||
if !handle.is_null() { | ||
self.unity_entry = Some(handle); | ||
} | ||
} | ||
} | ||
} | ||
|
||
properties.progress = Some(progress as f64 / 100.0); | ||
fn is_unity_running(&self) -> bool { | ||
if let Some(inspector) = self.unity_inspector { | ||
if let Some(unity_lib) = &self.unity_lib { | ||
return unsafe { unity_lib.unity_inspector_get_unity_running(inspector) } == 1; | ||
} | ||
} | ||
|
||
if let Some(state) = progress.state { | ||
properties.progress_visible = Some(!matches!(state, ProgressState::None)); | ||
false | ||
} | ||
|
||
pub fn update(&mut self, progress: ProgressBarState) { | ||
if let Some(uri) = progress.desktop_filename { | ||
self.desktop_filename = Some(uri); | ||
} | ||
|
||
if !self.is_supported { | ||
return; | ||
} | ||
|
||
self.ensure_lib_load(); | ||
|
||
if !self.is_unity_running() { | ||
return; | ||
} | ||
|
||
let signal = Message::signal("/", "com.canonical.Unity.LauncherEntry", "Update")? | ||
.build(&(self.app_uri.clone(), properties))?; | ||
if let Some(uri) = &self.desktop_filename { | ||
self.desktop_filename_c_str = Some(CString::new(uri.as_str()).unwrap_or_default()); | ||
} | ||
|
||
if self.unity_entry.is_none() { | ||
self.ensure_entry_load(); | ||
} | ||
if let Some(unity_lib) = &self.unity_lib { | ||
if let Some(unity_entry) = &self.unity_entry { | ||
if let Some(progress) = progress.progress { | ||
let progress = if progress > 100 { 100 } else { progress }; | ||
let progress = progress as f64 / 100.0; | ||
unsafe { (unity_lib.unity_launcher_entry_set_progress)(*unity_entry, progress) }; | ||
} | ||
|
||
self.conn.send(&signal)?; | ||
Ok(()) | ||
if let Some(state) = progress.state { | ||
let is_visible = !matches!(state, ProgressState::None); | ||
unsafe { | ||
(unity_lib.unity_launcher_entry_set_progress_visible)( | ||
*unity_entry, | ||
if is_visible { 1 } else { 0 }, | ||
) | ||
}; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub fn is_supported() -> bool { | ||
std::env::var("XDG_CURRENT_DESKTOP") | ||
.map(|d| { | ||
let d = d.to_lowercase(); | ||
d.contains("unity") || d.contains("gnome") | ||
}) | ||
.unwrap_or(false) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters