tenseleyflow/hyprkvm / 0e0f561

Browse files

debugging left edge triggering and network problems

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
0e0f561ed1aa594c1ed0d7e2c1f22bfaf4e469c5
Parents
f807d0a
Tree
ee73e24

1 changed file

StatusFile+-
M hyprkvm-daemon/src/input/capture.rs 126 28
hyprkvm-daemon/src/input/capture.rsmodified
@@ -53,7 +53,7 @@ pub struct EdgeCaptureConfig {
5353
 impl Default for EdgeCaptureConfig {
5454
     fn default() -> Self {
5555
         Self {
56
-            barrier_size: 1,
56
+            barrier_size: 5, // 5 pixels to ensure we catch events
5757
             enabled_edges: vec![
5858
                 Direction::Left,
5959
                 Direction::Right,
@@ -89,6 +89,13 @@ struct EdgeCaptureState {
8989
 
9090
     // Track outputs for barrier sizing
9191
     outputs: Vec<OutputInfo>,
92
+
93
+    // Track which barrier surface the pointer is currently on
94
+    active_barrier_idx: Option<usize>,
95
+    // Last position on barrier (for detecting edge-pushing motion)
96
+    last_barrier_pos: (f64, f64),
97
+    // Debounce: last time we sent an event for each direction
98
+    last_trigger_time: std::collections::HashMap<Direction, Instant>,
9299
 }
93100
 
94101
 #[derive(Debug, Clone)]
@@ -104,41 +111,51 @@ impl EdgeCaptureState {
104111
     fn create_barriers(&mut self, qh: &QueueHandle<Self>) {
105112
         // Get total screen bounds
106113
         let (min_x, min_y, max_x, max_y) = self.screen_bounds();
107
-        let total_width = (max_x - min_x) as u32;
108
-        let total_height = (max_y - min_y) as u32;
109114
 
110115
         for direction in &self.config.enabled_edges.clone() {
116
+            // Find the correct output for this edge direction
117
+            let target_output = self.find_edge_output(*direction);
118
+
111119
             let (width, height, anchor) = match direction {
112120
                 Direction::Left => (
113121
                     self.config.barrier_size,
114
-                    total_height,
122
+                    target_output.as_ref().map(|o| o.height).unwrap_or((max_y - min_y) as u32),
115123
                     Anchor::LEFT | Anchor::TOP | Anchor::BOTTOM,
116124
                 ),
117125
                 Direction::Right => (
118126
                     self.config.barrier_size,
119
-                    total_height,
127
+                    target_output.as_ref().map(|o| o.height).unwrap_or((max_y - min_y) as u32),
120128
                     Anchor::RIGHT | Anchor::TOP | Anchor::BOTTOM,
121129
                 ),
122130
                 Direction::Up => (
123
-                    total_width,
131
+                    target_output.as_ref().map(|o| o.width).unwrap_or((max_x - min_x) as u32),
124132
                     self.config.barrier_size,
125133
                     Anchor::TOP | Anchor::LEFT | Anchor::RIGHT,
126134
                 ),
127135
                 Direction::Down => (
128
-                    total_width,
136
+                    target_output.as_ref().map(|o| o.width).unwrap_or((max_x - min_x) as u32),
129137
                     self.config.barrier_size,
130138
                     Anchor::BOTTOM | Anchor::LEFT | Anchor::RIGHT,
131139
                 ),
132140
             };
133141
 
134
-            // Create layer surface
142
+            // Create layer surface on the specific edge output
135143
             let surface = self.compositor_state.create_surface(qh);
144
+            let output_ref = target_output.as_ref().map(|o| &o.output);
136145
             let layer_surface = self.layer_shell.create_layer_surface(
137146
                 qh,
138147
                 surface,
139148
                 Layer::Top, // Top layer to catch pointer
140149
                 Some(format!("hyprkvm-edge-{}", direction)),
141
-                None, // No specific output, use focused
150
+                output_ref,
151
+            );
152
+
153
+            tracing::info!(
154
+                "Creating {:?} barrier on output {:?}, size {}x{}",
155
+                direction,
156
+                target_output.as_ref().map(|o| format!("at ({}, {})", o.x, o.y)),
157
+                width,
158
+                height
142159
             );
143160
 
144161
             // Configure the layer surface
@@ -397,27 +414,105 @@ impl PointerHandler for EdgeCaptureState {
397414
         _pointer: &wl_pointer::WlPointer,
398415
         events: &[PointerEvent],
399416
     ) {
417
+        const DEBOUNCE_MS: u128 = 300; // Minimum time between triggers
418
+        const EDGE_THRESHOLD: f64 = 2.0; // Position threshold for "at edge"
419
+
400420
         for event in events {
401
-            if let PointerEventKind::Enter { .. } = event.kind {
402
-                // Pointer entered one of our barrier surfaces
403
-                let surface = &event.surface;
404
-                if let Some(idx) = self.find_barrier_by_surface(surface) {
405
-                    let barrier = &self.barriers[idx];
406
-                    let edge_event = EdgeEvent {
407
-                        direction: barrier.direction,
408
-                        position: (event.position.0 as i32, event.position.1 as i32),
409
-                        timestamp: Instant::now(),
410
-                    };
411
-
412
-                    tracing::info!(
413
-                        "Edge hit: {:?} at ({}, {})",
414
-                        barrier.direction,
415
-                        event.position.0,
416
-                        event.position.1
417
-                    );
418
-
419
-                    let _ = self.event_tx.send(edge_event);
421
+            match &event.kind {
422
+                PointerEventKind::Enter { .. } => {
423
+                    // Pointer entered one of our barrier surfaces
424
+                    if let Some(idx) = self.find_barrier_by_surface(&event.surface) {
425
+                        self.active_barrier_idx = Some(idx);
426
+                        self.last_barrier_pos = event.position;
427
+                        tracing::debug!(
428
+                            "Pointer entered {:?} barrier at ({}, {})",
429
+                            self.barriers[idx].direction,
430
+                            event.position.0,
431
+                            event.position.1
432
+                        );
433
+                    }
434
+                }
435
+                PointerEventKind::Leave { .. } => {
436
+                    if self.find_barrier_by_surface(&event.surface).is_some() {
437
+                        self.active_barrier_idx = None;
438
+                        tracing::debug!("Pointer left barrier");
439
+                    }
440
+                }
441
+                PointerEventKind::Motion { .. } => {
442
+                    // Check if we're on a barrier surface and detect edge-pushing motion
443
+                    if let Some(idx) = self.active_barrier_idx {
444
+                        let barrier = &self.barriers[idx];
445
+                        let (x, y) = event.position;
446
+                        let (last_x, last_y) = self.last_barrier_pos;
447
+
448
+                        tracing::trace!(
449
+                            "Motion on {:?} barrier: pos=({:.1}, {:.1}) last=({:.1}, {:.1}) size={}x{}",
450
+                            barrier.direction,
451
+                            x, y, last_x, last_y, barrier.width, barrier.height
452
+                        );
453
+
454
+                        // Calculate motion delta
455
+                        let dx = x - last_x;
456
+                        let dy = y - last_y;
457
+
458
+                        // Check if motion is toward the edge while at the edge
459
+                        let is_edge_push = match barrier.direction {
460
+                            Direction::Left => x <= EDGE_THRESHOLD && dx < -0.1,
461
+                            Direction::Right => x >= (barrier.width as f64 - EDGE_THRESHOLD) && dx > 0.1,
462
+                            Direction::Up => y <= EDGE_THRESHOLD && dy < -0.1,
463
+                            Direction::Down => y >= (barrier.height as f64 - EDGE_THRESHOLD) && dy > 0.1,
464
+                        };
465
+
466
+                        // Also trigger if cursor is stuck at edge position (x=0 or similar)
467
+                        let is_at_edge = match barrier.direction {
468
+                            Direction::Left => x < 1.0,
469
+                            Direction::Right => x > (barrier.width as f64 - 1.0),
470
+                            Direction::Up => y < 1.0,
471
+                            Direction::Down => y > (barrier.height as f64 - 1.0),
472
+                        };
473
+
474
+                        if is_edge_push || is_at_edge {
475
+                            // Check debounce
476
+                            let now = Instant::now();
477
+                            let should_trigger = self
478
+                                .last_trigger_time
479
+                                .get(&barrier.direction)
480
+                                .map(|t| now.duration_since(*t).as_millis() >= DEBOUNCE_MS)
481
+                                .unwrap_or(true);
482
+
483
+                            if should_trigger {
484
+                                self.last_trigger_time.insert(barrier.direction, now);
485
+
486
+                                // Calculate screen position
487
+                                let (min_x, min_y, max_x, max_y) = self.screen_bounds();
488
+                                let screen_pos = match barrier.direction {
489
+                                    Direction::Left => (min_x, min_y + y as i32),
490
+                                    Direction::Right => (max_x - 1, min_y + y as i32),
491
+                                    Direction::Up => (min_x + x as i32, min_y),
492
+                                    Direction::Down => (min_x + x as i32, max_y - 1),
493
+                                };
494
+
495
+                                let edge_event = EdgeEvent {
496
+                                    direction: barrier.direction,
497
+                                    position: screen_pos,
498
+                                    timestamp: now,
499
+                                };
500
+
501
+                                tracing::info!(
502
+                                    "Edge trigger: {:?} at screen ({}, {})",
503
+                                    barrier.direction,
504
+                                    screen_pos.0,
505
+                                    screen_pos.1
506
+                                );
507
+
508
+                                let _ = self.event_tx.send(edge_event);
509
+                            }
510
+                        }
511
+
512
+                        self.last_barrier_pos = event.position;
513
+                    }
420514
                 }
515
+                _ => {}
421516
             }
422517
         }
423518
     }
@@ -515,6 +610,9 @@ fn run_capture_loop(
515610
         event_tx,
516611
         config,
517612
         outputs: Vec::new(),
613
+        active_barrier_idx: None,
614
+        last_barrier_pos: (0.0, 0.0),
615
+        last_trigger_time: std::collections::HashMap::new(),
518616
     };
519617
 
520618
     // Initial roundtrip to get outputs