Skip to content

Commit

Permalink
Implement The Requested Changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ahqsoftwares committed Jun 19, 2023
1 parent a54b33f commit 9c8613c
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 264 deletions.
17 changes: 10 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,21 +170,24 @@ extern crate bitflags;
#[macro_use]
extern crate objc;

/// Taskbar Progress State
pub enum TaskbarProgressState {
/// Progress State
pub enum ProgressState {
None,
Normal,
/// **Treated as Normal in linux**
Intermediate,
/// **Treated as Normal in linux**
Paused,
/// **Treated as Normal in linux**
Error,
}

/// A struct describing the state of the progress bar
pub struct ProgressBarState {
/// The progress bar state
pub state: Option<TaskbarProgressState>,
/// The progress bar state.
pub state: Option<ProgressState>,
/// The progress bar progress. This can be a value ranging from `0` to `100`
pub progress: Option<f64>,
/// An identifier for your app to communicate with the Unity desktop window manager **Linux Only**
pub progress: Option<u64>,
/// The identifier for your app to communicate with the Unity desktop window manager **Linux Only**
pub unity_uri: Option<String>,
}

Expand Down
28 changes: 0 additions & 28 deletions src/platform/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use crate::{
event_loop::{EventLoop, EventLoopWindowTarget},
platform_impl::{x11::xdisplay::XError, Parent},
window::{Window, WindowBuilder},
ProgressBarState, TaskbarProgressState,
};

use self::x11::xdisplay::XConnection;
Expand All @@ -33,11 +32,6 @@ pub trait WindowExtUnix {

/// Whether to show the window icon in the taskbar or not.
fn set_skip_taskbar(&self, skip: bool);

/// Sets the taskbar progress state./
/// ## NOTE
/// - On **Linux:** App must be installed using .deb binary, Might not work on some distros like Linux Mint (Cinnamon)
fn set_progress_bar(&self, state: ProgressBarState);
}

impl WindowExtUnix for Window {
Expand All @@ -48,28 +42,6 @@ impl WindowExtUnix for Window {
fn set_skip_taskbar(&self, skip: bool) {
self.window.set_skip_taskbar(skip);
}

fn set_progress_bar(&self, progress: ProgressBarState) {
if let Some(state) = progress.state {
let taskbar_state = {
match state {
TaskbarProgressState::None => false,
_ => true,
}
};

self
.window
.set_taskbar_progress_state(taskbar_state, progress.unity_uri.clone());
}
if let Some(value) = progress.progress {
let progress_num = if value > 100 { 100f64 } else { value };

self
.window
.set_taskbar_progress(progress_num, progress.unity_uri.clone());
}
}
}

pub trait WindowBuilderExtUnix {
Expand Down
25 changes: 0 additions & 25 deletions src/platform/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use crate::{
monitor::MonitorHandle,
platform_impl::{EventLoop as WindowsEventLoop, Parent, WinIcon},
window::{BadIcon, Icon, Theme, Window, WindowBuilder},
ProgressBarState, TaskbarProgressState,
};
use libc;
use windows::Win32::{
Expand Down Expand Up @@ -118,9 +117,6 @@ pub trait WindowExtWindows {
/// Whether to show the window icon in the taskbar or not.
fn set_skip_taskbar(&self, skip: bool);

/// Sets the taskbar progress state./
fn set_progress_bar(&self, progress: ProgressBarState);

/// Shows or hides the background drop shadow for undecorated windows.
///
/// Enabling the shadow causes a thin 1px line to appear on the top of the window.
Expand Down Expand Up @@ -170,27 +166,6 @@ impl WindowExtWindows for Window {
self.window.set_skip_taskbar(skip);
}

#[inline]
fn set_progress_bar(&self, progress: ProgressBarState) {
if let Some(state) = progress.state {
let taskbar_state = {
match state {
TaskbarProgressState::None => 0,
TaskbarProgressState::Intermediate => 1,
TaskbarProgressState::Normal => 2,
TaskbarProgressState::Paused => 4,
}
};

self.window.set_taskbar_progress_state(taskbar_state);
}
if let Some(value) = progress.progress {
let progress = if value > 100 { 100f64 } else { value };

self.window.set_taskbar_progress(progress);
}
}

#[inline]
fn set_undecorated_shadow(&self, shadow: bool) {
self.window.set_undecorated_shadow(shadow)
Expand Down
31 changes: 5 additions & 26 deletions src/platform_impl/linux/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,37 +316,16 @@ impl<T: 'static> EventLoop<T> {
window.set_skip_taskbar_hint(skip);
window.set_skip_pager_hint(skip)
}
WindowRequest::TaskbarProgress(progress, unity_uri) => {
WindowRequest::PrgoressBarState(state) => {
if taskbar.is_none() {
taskbar.replace(TaskbarIndicator::new());
}

if let Some(taskbar) = &mut taskbar {
if let Some(unity_uri) = &unity_uri {
if let Err(e) = taskbar.set_unity_app_uri(unity_uri) {
log::warn!("Failed to set unity app uri {}", e);
}
}

if let Err(e) = taskbar.set_progress(progress) {
log::warn!("Failed to set progres: {}", e);
if let Ok(indicator) = TaskbarIndicator::new() {
taskbar.replace(indicator);
}
}
}
WindowRequest::TaskbarProgressState(state, unity_uri) => {
if taskbar.is_none() {
taskbar.replace(TaskbarIndicator::new());
}

if let Some(taskbar) = &mut taskbar {
if let Some(unity_uri) = &unity_uri {
if let Err(e) = taskbar.set_unity_app_uri(unity_uri) {
log::warn!("Failed to set unity app uri {}", e);
}
}

if let Err(e) = taskbar.set_progress_state(state) {
log::warn!("Failed to set progres: {}", e);
if let Err(e) = taskbar.update(state) {
log::warn!("Failed to set taskbar progress {}", e);
}
}
}
Expand Down
89 changes: 41 additions & 48 deletions src/platform_impl/linux/taskbar.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,59 @@
mod unity;
use crate::{ProgressBarState, ProgressState};
use zbus::{
blocking::Connection,
fdo::Result,
zvariant::{DeserializeDict, SerializeDict, Type},
MessageBuilder,
};

pub struct TaskbarIndicator {
unity: Option<unity::Manager>,
progress: f64,
progress_visible: bool,
needs_attention: bool,
conn: Connection,
app_uri: String,
}

#[allow(dead_code)]
impl TaskbarIndicator {
pub fn new() -> Self {
Self {
unity: None,
progress: 0.0,
progress_visible: false,
needs_attention: false,
}
}

pub fn set_unity_app_uri(&mut self, uri: impl AsRef<str>) -> Result<(), zbus::Error> {
let mut unity = unity::Manager::new(uri.as_ref().to_owned())?;

unity.set_progress(self.progress).unwrap_or(());
unity
.set_progress_visible(self.progress_visible)
.unwrap_or(());
unity.needs_attention(self.needs_attention).unwrap_or(());
#[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>,
}

self.unity.replace(unity);
impl TaskbarIndicator {
pub fn new() -> Result<Self> {
let conn = Connection::session()?;

Ok(())
Ok(Self {
conn,
app_uri: String::new(),
})
}

pub fn set_progress(&mut self, progress: f64) -> Result<(), Box<dyn std::error::Error>> {
self.set_progress_state(true)?;
pub fn update(&mut self, progress: ProgressBarState) -> Result<()> {
let mut properties = Progress::default();

self.progress = progress;

if let Some(ref mut unity) = self.unity {
unity.set_progress(progress)?;
if let Some(uri) = progress.unity_uri {
self.app_uri = uri;
}
Ok(())
}

pub fn set_progress_state(&mut self, visible: bool) -> Result<(), Box<dyn std::error::Error>> {
self.progress_visible = visible;
if let Some(progress) = progress.progress {
let progress = if progress > 100 { 100 } else { progress };

if let Some(ref mut unity) = self.unity {
unity.set_progress_visible(visible)?;
properties.progress = Some(progress as f64 / 100.0);
}
Ok(())
}

pub fn needs_attention(
&mut self,
needs_attention: bool,
) -> Result<(), Box<dyn std::error::Error>> {
self.needs_attention = needs_attention;

if let Some(ref mut unity) = self.unity {
unity.needs_attention(needs_attention)?;
if let Some(state) = progress.state {
match state {
ProgressState::None => properties.progress_visible = Some(false),
_ => properties.progress_visible = Some(true),
}
}

let signal = MessageBuilder::signal("/", "com.canonical.Unity.LauncherEntry", "Update")?
.build(&(self.app_uri.clone(), properties))?;

self.conn.send_message(signal).unwrap();
Ok(())
}
}
92 changes: 0 additions & 92 deletions src/platform_impl/linux/taskbar/unity.rs

This file was deleted.

Loading

0 comments on commit 9c8613c

Please sign in to comment.