gardesk/gar / a6575bf

Browse files

fix: translate frame windows to clients for tiled edge resize

When windows are reparented into frames (for title bars), motion and
button events come from the frame window, not the client. This fix:

- Translates frame window IDs to client IDs in motion/button handlers
- Sets/clears cursor on both frame and client windows
- Fixes tiled edge resize not detecting edges when frames are enabled
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
a6575bf603e5b9a66e75ad29ad9dbb429d1f6dcb
Parents
c62a2ae
Tree
7bef551

1 changed file

StatusFile+-
M gar/src/x11/events.rs 26 7
gar/src/x11/events.rsmodified
@@ -620,9 +620,11 @@ impl WindowManager {
620
     }
620
     }
621
 
621
 
622
     fn handle_button_press(&mut self, event: ButtonPressEvent) -> Result<()> {
622
     fn handle_button_press(&mut self, event: ButtonPressEvent) -> Result<()> {
623
-        let window = event.event;
623
+        let event_window = event.event;
624
         let child = event.child;
624
         let child = event.child;
625
-        tracing::debug!("ButtonPress on window {}, child {}, button {}", window, child, event.detail);
625
+        // Translate frame window to client window if needed
626
+        let window = self.frames.client_for_frame(event_window).unwrap_or(event_window);
627
+        tracing::debug!("ButtonPress on window {} (event_window={}), child {}, button {}", window, event_window, child, event.detail);
626
 
628
 
627
         // If we're already in a drag, ignore additional button presses
629
         // If we're already in a drag, ignore additional button presses
628
         if self.drag_state.is_some() {
630
         if self.drag_state.is_some() {
@@ -898,7 +900,10 @@ impl WindowManager {
898
     fn handle_motion_notify(&mut self, event: MotionNotifyEvent) -> Result<()> {
900
     fn handle_motion_notify(&mut self, event: MotionNotifyEvent) -> Result<()> {
899
         // If not in a drag, check for edge cursor changes
901
         // If not in a drag, check for edge cursor changes
900
         if self.drag_state.is_none() {
902
         if self.drag_state.is_none() {
901
-            let window = event.event;
903
+            let event_window = event.event;
904
+            // Translate frame window to client window if needed
905
+            let window = self.frames.client_for_frame(event_window).unwrap_or(event_window);
906
+
902
             if self.windows.contains_key(&window) {
907
             if self.windows.contains_key(&window) {
903
                 if self.is_floating(window) {
908
                 if self.is_floating(window) {
904
                     self.update_edge_cursor(window, event.root_x, event.root_y)?;
909
                     self.update_edge_cursor(window, event.root_x, event.root_y)?;
@@ -1141,18 +1146,32 @@ impl WindowManager {
1141
             return Ok(()); // No change
1146
             return Ok(()); // No change
1142
         }
1147
         }
1143
 
1148
 
1144
-        // Clear old cursor state
1149
+        // Clear old cursor state (use frame windows if they exist)
1145
         if let Some((old_w1, old_w2, _)) = self.tiled_edge_cursor {
1150
         if let Some((old_w1, old_w2, _)) = self.tiled_edge_cursor {
1146
-            self.conn.clear_window_cursor(old_w1)?;
1151
+            let frame1 = self.frames.frame_for_client(old_w1).unwrap_or(old_w1);
1147
-            self.conn.clear_window_cursor(old_w2)?;
1152
+            let frame2 = self.frames.frame_for_client(old_w2).unwrap_or(old_w2);
1153
+            self.conn.clear_window_cursor(frame1)?;
1154
+            self.conn.clear_window_cursor(frame2)?;
1155
+            // Also clear on client windows in case they don't have frames
1156
+            if frame1 != old_w1 {
1157
+                self.conn.clear_window_cursor(old_w1)?;
1158
+            }
1159
+            if frame2 != old_w2 {
1160
+                self.conn.clear_window_cursor(old_w2)?;
1161
+            }
1148
         }
1162
         }
1149
 
1163
 
1150
         if let Some((w1, w2, dir)) = new_state {
1164
         if let Some((w1, w2, dir)) = new_state {
1151
-            // Set resize cursor on both windows sharing the edge
1165
+            // Set resize cursor on both windows sharing the edge (and their frames)
1152
             let cursor = match dir {
1166
             let cursor = match dir {
1153
                 Direction::Left | Direction::Right => self.conn.cursor_h_double,
1167
                 Direction::Left | Direction::Right => self.conn.cursor_h_double,
1154
                 Direction::Up | Direction::Down => self.conn.cursor_v_double,
1168
                 Direction::Up | Direction::Down => self.conn.cursor_v_double,
1155
             };
1169
             };
1170
+            let frame1 = self.frames.frame_for_client(w1).unwrap_or(w1);
1171
+            let frame2 = self.frames.frame_for_client(w2).unwrap_or(w2);
1172
+            self.conn.set_window_cursor(frame1, cursor)?;
1173
+            self.conn.set_window_cursor(frame2, cursor)?;
1174
+            // Also set on client windows
1156
             self.conn.set_window_cursor(w1, cursor)?;
1175
             self.conn.set_window_cursor(w1, cursor)?;
1157
             self.conn.set_window_cursor(w2, cursor)?;
1176
             self.conn.set_window_cursor(w2, cursor)?;
1158
         }
1177
         }