@@ -12,7 +12,55 @@ pub fn focus_in_direction(
12
12
origin_container : & Container ,
13
13
direction : & Direction ,
14
14
state : & mut WmState ,
15
+ cycle_accordions : bool , // New parameter
15
16
) -> anyhow:: Result < ( ) > {
17
+ // First, check if we're in an accordion and shouldn't cycle
18
+ if !cycle_accordions {
19
+ let is_in_accordion = if let Some ( parent) = origin_container. parent ( ) {
20
+ if let Ok ( direction_parent) = parent. as_direction_container ( ) {
21
+ matches ! (
22
+ direction_parent. tiling_direction( ) ,
23
+ TilingDirection :: HorizontalAccordion
24
+ | TilingDirection :: VerticalAccordion
25
+ )
26
+ } else {
27
+ false
28
+ }
29
+ } else {
30
+ false
31
+ } ;
32
+
33
+ // If in accordion but not cycling, treat the whole accordion as one
34
+ // unit
35
+ if is_in_accordion {
36
+ // Find the accordion container
37
+ let accordion_parent = origin_container
38
+ . parent ( )
39
+ . and_then ( |p| p. as_direction_container ( ) . ok ( ) )
40
+ . context ( "No direction container" ) ?;
41
+
42
+ // We'll convert it to container once and use that
43
+ let accordion_container = accordion_parent. clone ( ) . into ( ) ;
44
+
45
+ // Try to move from the accordion to the next container
46
+ // Use the accordion parent as the origin instead of the window
47
+ let workspace_target =
48
+ workspace_focus_target ( & accordion_container, direction, state)
49
+ . ok ( )
50
+ . flatten ( ) ;
51
+ let tiling_target =
52
+ tiling_focus_target ( & accordion_container, direction) ?;
53
+ let focus_target = tiling_target. or ( workspace_target) ;
54
+
55
+ if let Some ( focus_target) = focus_target {
56
+ set_focused_descendant ( & focus_target, None ) ;
57
+ state. pending_sync . queue_focus_change ( ) . queue_cursor_jump ( ) ;
58
+ }
59
+
60
+ return Ok ( ( ) ) ;
61
+ }
62
+ }
63
+
16
64
let focus_target = match origin_container {
17
65
Container :: TilingWindow ( _) => {
18
66
// If a suitable focus target isn't found in the current workspace,
@@ -85,67 +133,41 @@ fn tiling_focus_target(
85
133
let tiling_direction = TilingDirection :: from_direction ( direction) ;
86
134
let mut origin_or_ancestor = origin_container. clone ( ) ;
87
135
88
- // First check if we're in an accordion container
89
- if let Some ( parent) = origin_or_ancestor. parent ( ) {
136
+ // Check if origin is in an accordion and if direction is valid for that
137
+ // accordion
138
+ let in_accordion = if let Some ( parent) = origin_or_ancestor. parent ( ) {
90
139
if let Ok ( direction_parent) = parent. as_direction_container ( ) {
91
140
match direction_parent. tiling_direction ( ) {
92
141
TilingDirection :: HorizontalAccordion => {
93
- match direction {
94
- Direction :: Up => {
95
- // Try to focus previous sibling in accordion
96
- if let Some ( prev) = origin_or_ancestor
97
- . prev_siblings ( )
98
- . find_map ( |c| c. as_tiling_container ( ) . ok ( ) )
99
- {
100
- return Ok ( Some ( prev. into ( ) ) ) ;
101
- }
102
- // If no previous sibling, allow falling through to normal
103
- // navigation
104
- }
105
- Direction :: Down => {
106
- // Try to focus next sibling in accordion
107
- if let Some ( next) = origin_or_ancestor
108
- . next_siblings ( )
109
- . find_map ( |c| c. as_tiling_container ( ) . ok ( ) )
110
- {
111
- return Ok ( Some ( next. into ( ) ) ) ;
112
- }
113
- // If no next sibling, allow falling through to normal
114
- // navigation
115
- }
116
- // For Left/Right, immediately pass through to normal
117
- // navigation
118
- _ => { }
119
- }
142
+ matches ! ( direction, Direction :: Up | Direction :: Down )
120
143
}
121
144
TilingDirection :: VerticalAccordion => {
122
- match direction {
123
- Direction :: Left => {
124
- if let Some ( prev) = origin_or_ancestor
125
- . prev_siblings ( )
126
- . find_map ( |c| c. as_tiling_container ( ) . ok ( ) )
127
- {
128
- return Ok ( Some ( prev. into ( ) ) ) ;
129
- }
130
- // If no previous sibling, allow falling through to normal
131
- // navigation
132
- }
133
- Direction :: Right => {
134
- if let Some ( next) = origin_or_ancestor
135
- . next_siblings ( )
136
- . find_map ( |c| c. as_tiling_container ( ) . ok ( ) )
137
- {
138
- return Ok ( Some ( next. into ( ) ) ) ;
139
- }
140
- // If no next sibling, allow falling through to normal
141
- // navigation
142
- }
143
- // For Up/Down, immediately pass through to normal navigation
144
- _ => { }
145
- }
145
+ matches ! ( direction, Direction :: Left | Direction :: Right )
146
146
}
147
- _ => { }
147
+ _ => false ,
148
148
}
149
+ } else {
150
+ false
151
+ }
152
+ } else {
153
+ false
154
+ } ;
155
+
156
+ // If we're in an accordion and moving in its main direction,
157
+ // handle accordion navigation directly
158
+ if in_accordion {
159
+ // Get the next/prev sibling depending on the direction
160
+ let focus_target = match direction {
161
+ Direction :: Up | Direction :: Left => origin_or_ancestor
162
+ . prev_siblings ( )
163
+ . find_map ( |c| c. as_tiling_container ( ) . ok ( ) ) ,
164
+ _ => origin_or_ancestor
165
+ . next_siblings ( )
166
+ . find_map ( |c| c. as_tiling_container ( ) . ok ( ) ) ,
167
+ } ;
168
+
169
+ if let Some ( target) = focus_target {
170
+ return Ok ( Some ( target. into ( ) ) ) ;
149
171
}
150
172
}
151
173
0 commit comments