fix(status-area): implement activate on left-click with menu fallback
This commit is contained in:
parent
2f1b47f2b8
commit
9db4ebdc2d
2 changed files with 57 additions and 14 deletions
|
|
@ -20,6 +20,8 @@ use crate::{components::status_menu, subscriptions::status_notifier_watcher};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Msg {
|
pub enum Msg {
|
||||||
|
None,
|
||||||
|
Activate(usize),
|
||||||
Closed(window::Id),
|
Closed(window::Id),
|
||||||
// XXX don't use index (unique window id? or I guess that's created and destroyed)
|
// XXX don't use index (unique window id? or I guess that's created and destroyed)
|
||||||
StatusMenu((usize, status_menu::Msg)),
|
StatusMenu((usize, status_menu::Msg)),
|
||||||
|
|
@ -100,10 +102,6 @@ impl App {
|
||||||
.on_enter(Msg::Hovered(*id))
|
.on_enter(Msg::Hovered(*id))
|
||||||
.into()
|
.into()
|
||||||
});
|
});
|
||||||
let theme = self.core.system_theme();
|
|
||||||
let cosmic = theme.cosmic();
|
|
||||||
let corners = cosmic.corner_radii;
|
|
||||||
let pad = corners.radius_m[0];
|
|
||||||
|
|
||||||
self.core
|
self.core
|
||||||
.applet
|
.applet
|
||||||
|
|
@ -151,6 +149,26 @@ impl cosmic::Application for App {
|
||||||
|
|
||||||
fn update(&mut self, message: Msg) -> app::Task<Msg> {
|
fn update(&mut self, message: Msg) -> app::Task<Msg> {
|
||||||
match message {
|
match message {
|
||||||
|
Msg::None => Task::none(),
|
||||||
|
Msg::Activate(id) => {
|
||||||
|
if let Some(token_tx) = self.token_tx.as_ref() {
|
||||||
|
let _ = token_tx.send(TokenRequest {
|
||||||
|
app_id: Self::APP_ID.to_string(),
|
||||||
|
exec: format!("activate:{}", id),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if let Some(menu) = self.menus.get(&id) {
|
||||||
|
let item_proxy = menu.item.item_proxy().clone();
|
||||||
|
return Task::future(async move {
|
||||||
|
match item_proxy.activate(0, 0).await {
|
||||||
|
Ok(_) => cosmic::action::app(Msg::None),
|
||||||
|
Err(_) => cosmic::action::app(Msg::TogglePopup(id)),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
Msg::Closed(surface) => {
|
Msg::Closed(surface) => {
|
||||||
if self.popup == Some(surface) {
|
if self.popup == Some(surface) {
|
||||||
self.popup = None;
|
self.popup = None;
|
||||||
|
|
@ -269,6 +287,36 @@ impl cosmic::Application for App {
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
TokenUpdate::ActivationToken { token, exec: id } => {
|
TokenUpdate::ActivationToken { token, exec: id } => {
|
||||||
|
if let Some(id_str) = id.strip_prefix("activate:") {
|
||||||
|
if let Ok(real_id) = id_str.parse::<usize>() {
|
||||||
|
if let Some(menu) = self.menus.get(&real_id) {
|
||||||
|
let item_proxy = menu.item.item_proxy().clone();
|
||||||
|
let token = token.clone();
|
||||||
|
let id = real_id;
|
||||||
|
return Task::future(async move {
|
||||||
|
if let Some(t) = token {
|
||||||
|
match item_proxy.provide_xdg_activation_token(t).await {
|
||||||
|
Ok(_) => {
|
||||||
|
println!("Token provided successfully to {}", id)
|
||||||
|
}
|
||||||
|
Err(e) => eprintln!(
|
||||||
|
"Failed to provide token to {}: {}",
|
||||||
|
id, e
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match item_proxy.activate(0, 0).await {
|
||||||
|
Ok(_) => cosmic::action::app(Msg::None),
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("Activate failed: {}", err);
|
||||||
|
cosmic::action::app(Msg::TogglePopup(id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Task::none();
|
||||||
|
}
|
||||||
if let Some(((state, id), token)) = str::parse(&id)
|
if let Some(((state, id), token)) = str::parse(&id)
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|id: usize| self.menus.get_mut(&id).map(|m| (m, id)))
|
.and_then(|id: usize| self.menus.get_mut(&id).map(|m| (m, id)))
|
||||||
|
|
@ -445,15 +493,10 @@ impl cosmic::Application for App {
|
||||||
.iter()
|
.iter()
|
||||||
.take(overflow_index.unwrap_or(self.menus.len()))
|
.take(overflow_index.unwrap_or(self.menus.len()))
|
||||||
.map(|(id, menu)| {
|
.map(|(id, menu)| {
|
||||||
mouse_area(menu_icon_button(&self.core.applet, &menu).on_press_down(
|
mouse_area(menu_icon_button(&self.core.applet, &menu).on_press(Msg::Activate(*id)))
|
||||||
if menu.item.menu_proxy().is_some() {
|
.on_right_press(Msg::TogglePopup(*id))
|
||||||
Msg::TogglePopup(*id)
|
.on_enter(Msg::Hovered(*id))
|
||||||
} else {
|
.into()
|
||||||
Msg::StatusMenu((*id, status_menu::Msg::Click(0, true)))
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.on_enter(Msg::Hovered(*id))
|
|
||||||
.into()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
self.core
|
self.core
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ impl StatusNotifierItem {
|
||||||
let menu_path = item_proxy.menu().await;
|
let menu_path = item_proxy.menu().await;
|
||||||
|
|
||||||
// Why would an item say it has no menu but provide a menu path? Slack does this.
|
// Why would an item say it has no menu but provide a menu path? Slack does this.
|
||||||
let mut is_menu = menu_path.is_ok() || is_menu.unwrap_or(false);
|
let is_menu = menu_path.is_ok() || is_menu.unwrap_or(false);
|
||||||
|
|
||||||
if !is_menu {
|
if !is_menu {
|
||||||
return Ok(Self {
|
return Ok(Self {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue