tenseleyflow/fackr / 6f0f03c

Browse files

feat: add pane hit testing for click-to-focus support

Add methods to determine which pane contains a screen coordinate:
- Tab::pane_at_screen_position() - finds pane by normalized coordinates
- Workspace::pane_at_position() - wrapper for active tab
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
6f0f03c197c444a25cf067b1bb0c378c11996f3d
Parents
dedbbc1
Tree
25dde3a

1 changed file

StatusFile+-
M src/workspace/state.rs 44 0
src/workspace/state.rsmodified
@@ -538,6 +538,34 @@ impl Tab {
538538
         self.panes.len()
539539
     }
540540
 
541
+    /// Find which pane contains a screen coordinate
542
+    /// Returns the pane index, or active_pane if no match found
543
+    pub fn pane_at_screen_position(&self, col: u16, row: u16, screen_cols: u16, screen_rows: u16, left_offset: u16, top_offset: u16) -> usize {
544
+        // Available space for panes (excluding fuss width and tab bar)
545
+        let available_width = screen_cols.saturating_sub(left_offset) as f32;
546
+        let available_height = screen_rows.saturating_sub(1 + top_offset) as f32; // -1 for status bar
547
+
548
+        // Adjust click coordinates for offsets
549
+        let adj_col = col.saturating_sub(left_offset) as f32;
550
+        let adj_row = row.saturating_sub(top_offset) as f32;
551
+
552
+        // Normalize coordinates to 0.0-1.0 range
553
+        let norm_x = adj_col / available_width;
554
+        let norm_y = adj_row / available_height;
555
+
556
+        // Find pane containing this normalized position
557
+        for (i, pane) in self.panes.iter().enumerate() {
558
+            if norm_x >= pane.bounds.x_start && norm_x < pane.bounds.x_end
559
+                && norm_y >= pane.bounds.y_start && norm_y < pane.bounds.y_end
560
+            {
561
+                return i;
562
+            }
563
+        }
564
+
565
+        // Default to active pane if no match
566
+        self.active_pane
567
+    }
568
+
541569
     /// Get the path of the primary buffer (for tab display and workspace tracking)
542570
     pub fn path(&self) -> Option<&PathBuf> {
543571
         self.buffers.first().and_then(|b| b.path.as_ref())
@@ -1139,4 +1167,20 @@ impl Workspace {
11391167
         }
11401168
         // Buffer automatically tracks modifications via content hash
11411169
     }
1170
+
1171
+    /// Find which pane in the active tab contains a screen coordinate
1172
+    /// Returns the pane index
1173
+    pub fn pane_at_position(&self, col: u16, row: u16, screen_cols: u16, screen_rows: u16) -> usize {
1174
+        // Calculate offsets for fuss mode and tab bar
1175
+        let fuss_width = if self.fuss.active {
1176
+            self.fuss.width(screen_cols)
1177
+        } else {
1178
+            0
1179
+        };
1180
+        let top_offset = if self.tabs.len() > 1 { 1u16 } else { 0 };
1181
+
1182
+        self.tabs[self.active_tab].pane_at_screen_position(
1183
+            col, row, screen_cols, screen_rows, fuss_width, top_offset
1184
+        )
1185
+    }
11421186
 }