gardesk/garnotify / 0e7907b

Browse files

feat(ui): add action click handling and hover effects

Handle mouse motion for button hover effects, and detect clicks
on action buttons to emit ActionInvoked signals.
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
0e7907b7978317ab7b4286ea8c8dff4dd846b5fc
Parents
3fec681
Tree
dc923a0

1 changed file

StatusFile+-
M garnotify/src/ui/popup_manager.rs 38 6
garnotify/src/ui/popup_manager.rsmodified
@@ -44,6 +44,7 @@ impl PopupManager {
4444
             config.geometry.width,
4545
             position,
4646
             config.geometry.max_visible,
47
+            &config.general.monitor,
4748
         );
4849
 
4950
         info!(
@@ -198,13 +199,28 @@ impl PopupManager {
198199
                 }
199200
             }
200201
             X11Event::ButtonPress(e) => {
201
-                // Click to dismiss
202202
                 if let Some(&id) = self.window_to_notification.get(&e.event) {
203
-                    info!("Click on notification {} - dismissing", id);
204
-                    self.close_notification(id, CloseReason::Dismissed)?;
205
-
206
-                    // Notify daemon
207
-                    let _ = self.event_tx.try_send(PopupEvent::Dismissed(id));
203
+                    // Check if click hit an action button
204
+                    if let Some(popup) = self.popups.get(&id) {
205
+                        // Convert root coordinates to window coordinates for action click check
206
+                        let action_key = popup.check_action_click(e.event_x as i32, e.event_y as i32);
207
+
208
+                        if let Some(key) = action_key {
209
+                            info!("Action '{}' invoked on notification {}", key, id);
210
+                            // Notify daemon of action
211
+                            let _ = self.event_tx.try_send(PopupEvent::ActionInvoked { id, action_key: key });
212
+
213
+                            // Close notification unless it's resident
214
+                            if !popup.notification().hints.resident {
215
+                                self.close_notification(id, CloseReason::Dismissed)?;
216
+                            }
217
+                        } else {
218
+                            // Click outside action buttons - dismiss
219
+                            info!("Click on notification {} - dismissing", id);
220
+                            self.close_notification(id, CloseReason::Dismissed)?;
221
+                            let _ = self.event_tx.try_send(PopupEvent::Dismissed(id));
222
+                        }
223
+                    }
208224
                 }
209225
             }
210226
             X11Event::EnterNotify(e) => {
@@ -218,6 +234,22 @@ impl PopupManager {
218234
                 if let Some(&id) = self.window_to_notification.get(&e.event) {
219235
                     if let Some(popup) = self.popups.get_mut(&id) {
220236
                         popup.on_leave();
237
+                        // Re-render to clear hover effects
238
+                        if let Err(e) = popup.render() {
239
+                            warn!("Failed to re-render on leave: {}", e);
240
+                        }
241
+                    }
242
+                }
243
+            }
244
+            X11Event::MotionNotify(e) => {
245
+                if let Some(&id) = self.window_to_notification.get(&e.event) {
246
+                    if let Some(popup) = self.popups.get_mut(&id) {
247
+                        // Update hover state, re-render if changed
248
+                        if popup.on_motion(e.event_x as i32, e.event_y as i32) {
249
+                            if let Err(err) = popup.render() {
250
+                                warn!("Failed to re-render on motion: {}", err);
251
+                            }
252
+                        }
221253
                     }
222254
                 }
223255
             }