From 2276d4658cfed2cfceaefed4a120960ee7bd4fe2 Mon Sep 17 00:00:00 2001 From: Yao Xiao <108576690+Charlie-XIAO@users.noreply.github.com> Date: Fri, 31 Jan 2025 20:24:19 -0500 Subject: [PATCH] refactor: avoid using macro where unnecessary (#376) --- .../src/states/canvas_click_through.rs | 113 ++++++++---------- .../src/states/widget_collection.rs | 53 +++----- crates/deskulpt-core/src/tray.rs | 69 +++++------ 3 files changed, 99 insertions(+), 136 deletions(-) diff --git a/crates/deskulpt-core/src/states/canvas_click_through.rs b/crates/deskulpt-core/src/states/canvas_click_through.rs index d1a22854..2fc50f6b 100644 --- a/crates/deskulpt-core/src/states/canvas_click_through.rs +++ b/crates/deskulpt-core/src/states/canvas_click_through.rs @@ -17,82 +17,69 @@ use crate::events::{EventsExt, ShowToastPayload}; struct CanvasClickThroughState(Mutex<(bool, Option>)>); /// Extension trait for operations on canvas click-through state. -pub trait StatesExtCanvasClickThrough { +pub trait StatesExtCanvasClickThrough: Manager + EventsExt { /// Initialize state management for whether the canvas is click-through. /// /// The canvas is click-through by default. - fn manage_canvas_click_through(&self); + fn manage_canvas_click_through(&self) { + self.manage(CanvasClickThroughState::(Mutex::new((true, None)))); + } /// Set the menu item for toggling the canvas click-through state. - fn set_canvas_click_through_menu_item(&self, menu_item: &MenuItem); + fn set_canvas_click_through_menu_item(&self, menu_item: &MenuItem) { + let state = self.state::>(); + let mut canvas_click_through = state.0.lock().unwrap(); + + // Cloning works because menu items are behind shared references + canvas_click_through.1 = Some(menu_item.clone()); + } /// Toggle the click-through state of the canvas window. /// /// This will also update the menu item text and show a toast message on the /// canvas if possible. - fn toggle_canvas_click_through(&self) -> Result<()>; -} - -/// Shared implementation of [`StatesExtCanvasClickThrough`]. -macro_rules! shared_impl { - ($app: ty) => { - impl StatesExtCanvasClickThrough for $app { - fn manage_canvas_click_through(&self) { - self.manage(CanvasClickThroughState::(Mutex::new((true, None)))); + fn toggle_canvas_click_through(&self) -> Result<()> { + let canvas = self + .get_webview_window("canvas") + .expect("Canvas window not found"); + + let state = self.state::>(); + let mut canvas_click_through = state.0.lock().unwrap(); + let prev_click_through = canvas_click_through.0; + canvas.set_ignore_cursor_events(!prev_click_through)?; + canvas_click_through.0 = !prev_click_through; + + let (menu_item_text, toast_message) = if prev_click_through { + // If the canvas is toggled to not click-through, try to regain + // focus to avoid flickering on the first click + if let Err(e) = canvas.set_focus() { + eprintln!("Failed to gain focus on canvas: {}", e); } - - fn set_canvas_click_through_menu_item(&self, menu_item: &MenuItem) { - let state = self.state::>(); - let mut canvas_click_through = state.0.lock().unwrap(); - - // Cloning works because menu items are behind shared references - canvas_click_through.1 = Some(menu_item.clone()); + ("Sink", "Canvas floated.") + } else { + ("Float", "Canvas sunk.") + }; + + // Update menu item text if it exists + if let Some(menu_item) = canvas_click_through.1.as_ref() { + if let Err(e) = menu_item.set_text(menu_item_text) { + eprintln!( + "Failed to update menu item for toggling canvas click-through: {}", + e + ); } + } - fn toggle_canvas_click_through(&self) -> Result<()> { - let canvas = self - .get_webview_window("canvas") - .expect("Canvas window not found"); - - let state = self.state::>(); - let mut canvas_click_through = state.0.lock().unwrap(); - let prev_click_through = canvas_click_through.0; - canvas.set_ignore_cursor_events(!prev_click_through)?; - canvas_click_through.0 = !prev_click_through; - - let (menu_item_text, toast_message) = if prev_click_through { - // If the canvas is toggled to not click-through, try to regain - // focus to avoid flickering on the first click - if let Err(e) = canvas.set_focus() { - eprintln!("Failed to gain focus on canvas: {}", e); - } - ("Sink", "Canvas floated.") - } else { - ("Float", "Canvas sunk.") - }; - - // Update menu item text if it exists - if let Some(menu_item) = canvas_click_through.1.as_ref() { - if let Err(e) = menu_item.set_text(menu_item_text) { - eprintln!( - "Failed to update menu item for toggling canvas click-through: {}", - e - ); - } - } - - // Show a toast message on the canvas - if let Err(e) = self - .emit_show_toast_to_canvas(ShowToastPayload::Success(toast_message.to_string())) - { - eprintln!("Failed to emit show-toast to canvas: {}", e); - } - - Ok(()) - } + // Show a toast message on the canvas + if let Err(e) = + self.emit_show_toast_to_canvas(ShowToastPayload::Success(toast_message.to_string())) + { + eprintln!("Failed to emit show-toast to canvas: {}", e); } - }; + + Ok(()) + } } -shared_impl!(App); -shared_impl!(AppHandle); +impl StatesExtCanvasClickThrough for App {} +impl StatesExtCanvasClickThrough for AppHandle {} diff --git a/crates/deskulpt-core/src/states/widget_collection.rs b/crates/deskulpt-core/src/states/widget_collection.rs index f8a5a984..ec0e9d8d 100644 --- a/crates/deskulpt-core/src/states/widget_collection.rs +++ b/crates/deskulpt-core/src/states/widget_collection.rs @@ -11,9 +11,11 @@ use crate::config::WidgetCollection; struct WidgetCollectionState(RwLock); /// Extension trait for operations on widget collection state. -pub trait StatesExtWidgetCollection { +pub trait StatesExtWidgetCollection: Manager { /// Initialize state management for the widget collection. - fn manage_widget_collection(&self); + fn manage_widget_collection(&self) { + self.manage(WidgetCollectionState::default()); + } /// Provide reference to the widget collection within a closure. /// @@ -21,7 +23,12 @@ pub trait StatesExtWidgetCollection { /// closure will be propagated. fn with_widget_collection(&self, f: F) -> T where - F: FnOnce(&WidgetCollection) -> T; + F: FnOnce(&WidgetCollection) -> T, + { + let state = self.state::(); + let widget_collection = state.0.read().unwrap(); + f(&widget_collection) + } /// Provide mutable reference to the widget collection within a closure. /// @@ -29,37 +36,13 @@ pub trait StatesExtWidgetCollection { /// closure will be propagated. fn with_widget_collection_mut(&self, f: F) -> T where - F: FnOnce(&mut WidgetCollection) -> T; + F: FnOnce(&mut WidgetCollection) -> T, + { + let state = self.state::(); + let mut widget_collection = state.0.write().unwrap(); + f(&mut widget_collection) + } } -/// Shared implementation of [`StatesExtWidgetCollection`]. -macro_rules! shared_impl { - ($app: ty) => { - impl StatesExtWidgetCollection for $app { - fn manage_widget_collection(&self) { - self.manage(WidgetCollectionState::default()); - } - - fn with_widget_collection(&self, f: F) -> T - where - F: FnOnce(&WidgetCollection) -> T, - { - let state = self.state::(); - let widget_collection = state.0.read().unwrap(); - f(&widget_collection) - } - - fn with_widget_collection_mut(&self, f: F) -> T - where - F: FnOnce(&mut WidgetCollection) -> T, - { - let state = self.state::(); - let mut widget_collection = state.0.write().unwrap(); - f(&mut widget_collection) - } - } - }; -} - -shared_impl!(App); -shared_impl!(AppHandle); +impl StatesExtWidgetCollection for App {} +impl StatesExtWidgetCollection for AppHandle {} diff --git a/crates/deskulpt-core/src/tray.rs b/crates/deskulpt-core/src/tray.rs index 0b1ad4e2..ca4b6657 100644 --- a/crates/deskulpt-core/src/tray.rs +++ b/crates/deskulpt-core/src/tray.rs @@ -6,7 +6,7 @@ use anyhow::Result; use tauri::image::Image; use tauri::menu::{MenuBuilder, MenuEvent, MenuItemBuilder}; use tauri::tray::{MouseButton, MouseButtonState, TrayIcon, TrayIconBuilder, TrayIconEvent}; -use tauri::{App, AppHandle, Runtime}; +use tauri::{App, AppHandle, Manager, Runtime}; use tokio::time::sleep; use crate::events::EventsExt; @@ -14,49 +14,42 @@ use crate::states::StatesExtCanvasClickThrough; use crate::window::WindowExt; /// Extention trait for system tray-related operations. -pub trait TrayExt { +pub trait TrayExt: Manager + StatesExtCanvasClickThrough { /// Create the system tray. - fn create_tray(&self, icon: Image) -> Result<()>; -} - -/// Shared implementation of [`TrayExt`]. -macro_rules! shared_impl { - ($app: ty) => { - impl TrayExt for $app { - fn create_tray(&self, icon: Image) -> Result<()> { - // Store the menu item for toggling canvas click-through - let menu_item_toggle = - MenuItemBuilder::with_id("tray-toggle", "Float").build(self)?; - self.set_canvas_click_through_menu_item(&menu_item_toggle); + fn create_tray(&self, icon: Image) -> Result<()> + where + Self: Sized, + { + // Store the menu item for toggling canvas click-through + let menu_item_toggle = MenuItemBuilder::with_id("tray-toggle", "Float").build(self)?; + self.set_canvas_click_through_menu_item(&menu_item_toggle); - // Build the system tray menu - let tray_menu = MenuBuilder::new(self) - .items(&[ - &menu_item_toggle, - &MenuItemBuilder::with_id("tray-manage", "Manage").build(self)?, - &MenuItemBuilder::with_id("tray-exit", "Exit").build(self)?, - ]) - .build()?; + // Build the system tray menu + let tray_menu = MenuBuilder::new(self) + .items(&[ + &menu_item_toggle, + &MenuItemBuilder::with_id("tray-manage", "Manage").build(self)?, + &MenuItemBuilder::with_id("tray-exit", "Exit").build(self)?, + ]) + .build()?; - // Build the system tray icon - TrayIconBuilder::with_id("tray") - .icon(icon) - .icon_as_template(true) - .show_menu_on_left_click(false) - .tooltip("Deskulpt") - .menu(&tray_menu) - .on_menu_event(on_menu_event) - .on_tray_icon_event(on_tray_icon_event) - .build(self)?; + // Build the system tray icon + TrayIconBuilder::with_id("tray") + .icon(icon) + .icon_as_template(true) + .show_menu_on_left_click(false) + .tooltip("Deskulpt") + .menu(&tray_menu) + .on_menu_event(on_menu_event) + .on_tray_icon_event(on_tray_icon_event) + .build(self)?; - Ok(()) - } - } - }; + Ok(()) + } } -shared_impl!(App); -shared_impl!(AppHandle); +impl TrayExt for App {} +impl TrayExt for AppHandle {} /// Handler for system tray menu events. ///