diff options
Diffstat (limited to 'sway/input_state.c')
-rw-r--r-- | sway/input_state.c | 230 |
1 files changed, 119 insertions, 111 deletions
diff --git a/sway/input_state.c b/sway/input_state.c index 3db78167..a63fc01c 100644 --- a/sway/input_state.c +++ b/sway/input_state.c | |||
@@ -48,75 +48,81 @@ void release_key(keycode key) { | |||
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | // Pointer state and mode | ||
52 | |||
51 | struct pointer_state pointer_state; | 53 | struct pointer_state pointer_state; |
52 | 54 | ||
53 | // Pointer mode values | ||
54 | static struct mode_state { | 55 | static struct mode_state { |
55 | // Initial view state | 56 | // initial view state |
57 | double x, y, w, h; | ||
58 | swayc_t *ptr; | ||
59 | // containers resized with tiling resize | ||
56 | struct { | 60 | struct { |
57 | double x, y, w, h; | 61 | double x, w; |
58 | swayc_t *ptr; | 62 | swayc_t *ptr; |
59 | } view; | 63 | } lr; |
60 | // Initial pointer state | ||
61 | struct { | 64 | struct { |
62 | int x, y; | 65 | double y, h; |
63 | } coor; | 66 | swayc_t *ptr; |
67 | } tb; | ||
64 | } initial; | 68 | } initial; |
65 | 69 | ||
66 | static struct { | 70 | static struct { |
67 | enum { LEFT=1, RIGHT=0 } lr; | 71 | bool left; |
68 | enum { TOP=1, BOTTOM=0 } tb; | 72 | bool top; |
69 | } lock; | 73 | } lock; |
70 | 74 | ||
71 | // Floating set/unset | 75 | // Floating set/unset |
72 | 76 | ||
73 | static void pointer_mode_set_floating(void) { | 77 | static void set_initial_view(swayc_t *view) { |
74 | initial.view.x = initial.view.ptr->x; | 78 | initial.ptr = view; |
75 | initial.view.y = initial.view.ptr->y; | 79 | initial.x = view->x; |
76 | initial.view.w = initial.view.ptr->width; | 80 | initial.y = view->y; |
77 | initial.view.h = initial.view.ptr->height; | 81 | initial.w = view->width; |
78 | // setup initial cooridinates | 82 | initial.h = view->height; |
79 | initial.coor.x = pointer_state.origin.x; | ||
80 | initial.coor.y = pointer_state.origin.y; | ||
81 | } | 83 | } |
82 | 84 | ||
83 | static void pointer_mode_reset_floating(void) { | 85 | static void reset_initial_view(void) { |
84 | initial.view.ptr->x = initial.view.x; | 86 | initial.ptr->x = initial.x; |
85 | initial.view.ptr->y = initial.view.y; | 87 | initial.ptr->y = initial.y; |
86 | initial.view.ptr->width = initial.view.w; | 88 | initial.ptr->width = initial.w; |
87 | initial.view.ptr->height = initial.view.h; | 89 | initial.ptr->height = initial.h; |
88 | arrange_windows(initial.view.ptr, -1, -1); | 90 | arrange_windows(initial.ptr, -1, -1); |
89 | pointer_state.mode = 0; | 91 | pointer_state.mode = 0; |
90 | } | 92 | } |
91 | 93 | ||
92 | // Mode set left/right click | 94 | // Mode set left/right click |
93 | 95 | ||
94 | static void pointer_mode_set_left(void) { | 96 | static void pointer_mode_set_left(void) { |
95 | swayc_t *view = pointer_state.view; | 97 | set_initial_view(pointer_state.left.view); |
96 | initial.view.ptr = view; | 98 | if (initial.ptr->is_floating) { |
97 | if (view->is_floating) { | ||
98 | pointer_state.mode = M_DRAGGING | M_FLOATING; | 99 | pointer_state.mode = M_DRAGGING | M_FLOATING; |
99 | pointer_mode_set_floating(); | ||
100 | } else { | 100 | } else { |
101 | pointer_state.mode = M_DRAGGING | M_TILING; | 101 | pointer_state.mode = M_DRAGGING | M_TILING; |
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | static void pointer_mode_set_right(void) { | 105 | static void pointer_mode_set_right(void) { |
106 | swayc_t *view = pointer_state.view; | 106 | set_initial_view(pointer_state.right.view); |
107 | initial.view.ptr = view; | ||
108 | // Setup locking information | 107 | // Setup locking information |
109 | int midway_x = view->x + view->width/2; | 108 | int midway_x = initial.ptr->x + initial.ptr->width/2; |
110 | int midway_y = view->y + view->height/2; | 109 | int midway_y = initial.ptr->y + initial.ptr->height/2; |
111 | 110 | ||
112 | lock.lr = pointer_state.origin.x > midway_x; | 111 | lock.left = pointer_state.origin.x > midway_x; |
113 | lock.tb = pointer_state.origin.y > midway_y; | 112 | lock.top = pointer_state.origin.y > midway_y; |
114 | 113 | ||
115 | if (view->is_floating) { | 114 | if (initial.ptr->is_floating) { |
116 | pointer_state.mode = M_RESIZING | M_FLOATING; | 115 | pointer_state.mode = M_RESIZING | M_FLOATING; |
117 | pointer_mode_set_floating(); | ||
118 | } else { | 116 | } else { |
119 | pointer_state.mode = M_RESIZING | M_TILING; | 117 | pointer_state.mode = M_RESIZING | M_TILING; |
118 | if ((initial.lr.ptr = get_swayc_in_direction(initial.ptr, lock.left ? MOVE_RIGHT: MOVE_LEFT))) { | ||
119 | initial.lr.x = initial.lr.ptr->x; | ||
120 | initial.lr.w = initial.lr.ptr->width; | ||
121 | } | ||
122 | if ((initial.tb.ptr = get_swayc_in_direction(initial.ptr, lock.top ? MOVE_DOWN: MOVE_UP))) { | ||
123 | initial.tb.y = initial.tb.ptr->y; | ||
124 | initial.tb.h = initial.tb.ptr->height; | ||
125 | } | ||
120 | } | 126 | } |
121 | } | 127 | } |
122 | 128 | ||
@@ -127,14 +133,14 @@ void pointer_mode_set(uint32_t button, bool condition) { | |||
127 | switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) { | 133 | switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) { |
128 | case M_DRAGGING: | 134 | case M_DRAGGING: |
129 | // end drag mode when left click is unpressed | 135 | // end drag mode when left click is unpressed |
130 | if (!pointer_state.l_held) { | 136 | if (!pointer_state.left.held) { |
131 | pointer_state.mode = 0; | 137 | pointer_state.mode = 0; |
132 | } | 138 | } |
133 | break; | 139 | break; |
134 | 140 | ||
135 | case M_RESIZING: | 141 | case M_RESIZING: |
136 | // end resize mode when right click is unpressed | 142 | // end resize mode when right click is unpressed |
137 | if (!pointer_state.r_held) { | 143 | if (!pointer_state.right.held) { |
138 | pointer_state.mode = 0; | 144 | pointer_state.mode = 0; |
139 | } | 145 | } |
140 | break; | 146 | break; |
@@ -145,12 +151,13 @@ void pointer_mode_set(uint32_t button, bool condition) { | |||
145 | if (!condition || !pointer_state.view) { | 151 | if (!condition || !pointer_state.view) { |
146 | break; | 152 | break; |
147 | } | 153 | } |
154 | |||
148 | // Set mode depending on current button press | 155 | // Set mode depending on current button press |
149 | switch (button) { | 156 | switch (button) { |
150 | // Start dragging mode | 157 | // Start dragging mode |
151 | case M_LEFT_CLICK: | 158 | case M_LEFT_CLICK: |
152 | // if button release dont do anything | 159 | // if button release dont do anything |
153 | if (pointer_state.l_held) { | 160 | if (pointer_state.left.held) { |
154 | pointer_mode_set_left(); | 161 | pointer_mode_set_left(); |
155 | } | 162 | } |
156 | break; | 163 | break; |
@@ -158,106 +165,131 @@ void pointer_mode_set(uint32_t button, bool condition) { | |||
158 | // Start resize mode | 165 | // Start resize mode |
159 | case M_RIGHT_CLICK: | 166 | case M_RIGHT_CLICK: |
160 | // if button release dont do anyhting | 167 | // if button release dont do anyhting |
161 | if (pointer_state.r_held) { | 168 | if (pointer_state.right.held) { |
162 | pointer_mode_set_right(); | 169 | pointer_mode_set_right(); |
163 | } | 170 | } |
164 | break; | 171 | break; |
165 | |||
166 | case M_SCROLL_UP: | ||
167 | case M_SCROLL_DOWN: | ||
168 | //TODO add scrolling behavior here | ||
169 | ; | ||
170 | } | 172 | } |
171 | } | 173 | } |
172 | } | 174 | } |
173 | 175 | ||
174 | void pointer_mode_update(void) { | 176 | void pointer_mode_update(void) { |
175 | swayc_t *view = initial.view.ptr; | 177 | if (initial.ptr->type != C_VIEW) { |
176 | if (view->type != C_VIEW) { | ||
177 | pointer_state.mode = 0; | 178 | pointer_state.mode = 0; |
178 | return; | 179 | return; |
179 | } | 180 | } |
180 | int dx = pointer_state.origin.x - initial.coor.x; | 181 | int dx = pointer_state.origin.x; |
181 | int dy = pointer_state.origin.y - initial.coor.y; | 182 | int dy = pointer_state.origin.y; |
182 | bool changed = false; | 183 | bool changed = false; |
183 | 184 | ||
184 | switch (pointer_state.mode) { | 185 | switch (pointer_state.mode) { |
185 | case M_FLOATING | M_DRAGGING: | 186 | case M_FLOATING | M_DRAGGING: |
186 | // Update position | 187 | // Update position |
187 | if (initial.view.x + dx != view->x) { | 188 | dx -= pointer_state.left.x; |
188 | view->x = initial.view.x + dx; | 189 | dy -= pointer_state.left.y; |
190 | if (initial.x + dx != initial.ptr->x) { | ||
191 | initial.ptr->x = initial.x + dx; | ||
189 | changed = true; | 192 | changed = true; |
190 | } | 193 | } |
191 | if (initial.view.y + dy != view->y) { | 194 | if (initial.y + dy != initial.ptr->y) { |
192 | view->y = initial.view.y + dy; | 195 | initial.ptr->y = initial.y + dy; |
193 | changed = true; | 196 | changed = true; |
194 | } | 197 | } |
198 | update_geometry(initial.ptr); | ||
195 | break; | 199 | break; |
196 | 200 | ||
197 | case M_FLOATING | M_RESIZING: | 201 | case M_FLOATING | M_RESIZING: |
198 | if (lock.lr) { | 202 | dx -= pointer_state.right.x; |
199 | if (initial.view.w + dx > min_sane_w) { | 203 | dy -= pointer_state.right.y; |
200 | if (initial.view.w + dx != view->width) { | 204 | initial.ptr = pointer_state.right.view; |
201 | view->width = initial.view.w + dx; | 205 | if (lock.left) { |
202 | changed = true; | 206 | if (initial.w + dx > min_sane_w) { |
203 | } | 207 | initial.ptr->width = initial.w + dx; |
204 | } | 208 | } |
205 | } else { //lock.right | 209 | } else { //lock.right |
206 | if (initial.view.w - dx > min_sane_w) { | 210 | if (initial.w - dx > min_sane_w) { |
207 | if (initial.view.w - dx != view->width) { | 211 | initial.ptr->width = initial.w - dx; |
208 | view->width = initial.view.w - dx; | 212 | initial.ptr->x = initial.x + dx; |
209 | view->x = initial.view.x + dx; | ||
210 | changed = true; | ||
211 | } | ||
212 | } | 213 | } |
213 | } | 214 | } |
214 | if (lock.tb) { | 215 | if (lock.top) { |
215 | if (initial.view.h + dy > min_sane_h) { | 216 | if (initial.h + dy > min_sane_h) { |
216 | if (initial.view.y - dy != view->height) { | 217 | initial.ptr->height = initial.h + dy; |
217 | view->height = initial.view.h + dy; | ||
218 | changed = true; | ||
219 | } | ||
220 | } | 218 | } |
221 | } else { //lock.bottom | 219 | } else { //lock.bottom |
222 | if (initial.view.h - dy > min_sane_h) { | 220 | if (initial.h - dy > min_sane_h) { |
223 | if (initial.view.h - dy != view->height) { | 221 | initial.ptr->height = initial.h - dy; |
224 | view->height = initial.view.h - dy; | 222 | initial.ptr->y = initial.y + dy; |
225 | view->y = initial.view.y + dy; | ||
226 | changed = true; | ||
227 | } | ||
228 | } | 223 | } |
229 | } | 224 | } |
225 | update_geometry(initial.ptr); | ||
230 | break; | 226 | break; |
231 | 227 | ||
232 | case M_TILING | M_DRAGGING: | 228 | case M_TILING | M_DRAGGING: |
233 | // swap current view under pointer with dragged view | 229 | // swap current view under pointer with dragged view |
234 | if (pointer_state.view && pointer_state.view != initial.view.ptr) { | 230 | if (pointer_state.view && pointer_state.view != initial.ptr) { |
235 | // Swap them around | 231 | // Swap them around |
236 | swap_container(pointer_state.view, initial.view.ptr); | 232 | swap_container(pointer_state.view, initial.ptr); |
237 | update_geometry(pointer_state.view); | 233 | update_geometry(pointer_state.view); |
238 | update_geometry(initial.view.ptr); | 234 | update_geometry(initial.ptr); |
239 | // Set focus back to initial view | 235 | // Set focus back to initial view |
240 | set_focused_container(initial.view.ptr); | 236 | set_focused_container(initial.ptr); |
241 | } | 237 | } |
242 | break; | 238 | break; |
243 | 239 | ||
244 | case M_TILING | M_RESIZING: | 240 | case M_TILING | M_RESIZING: |
245 | 241 | dx -= pointer_state.right.x; | |
246 | 242 | dy -= pointer_state.right.y; | |
247 | 243 | // resize if we can | |
244 | if (initial.lr.ptr) { | ||
245 | if (lock.left) { | ||
246 | // Check whether its fine to resize | ||
247 | if (initial.w + dx > min_sane_w && initial.lr.w - dx > min_sane_w) { | ||
248 | initial.ptr->width = initial.w + dx; | ||
249 | initial.lr.ptr->width = initial.lr.w - dx; | ||
250 | initial.lr.ptr->x = initial.lr.x + dx; | ||
251 | } | ||
252 | } else { //lock.right | ||
253 | if (initial.w - dx > min_sane_w && initial.lr.w + dx > min_sane_w) { | ||
254 | initial.ptr->width = initial.w - dx; | ||
255 | initial.ptr->x = initial.x + dx; | ||
256 | initial.lr.ptr->width = initial.lr.w + dx; | ||
257 | } | ||
258 | changed = true; | ||
259 | } | ||
260 | arrange_windows(initial.lr.ptr->parent, -1, -1); | ||
261 | } | ||
262 | if (initial.tb.ptr) { | ||
263 | if (lock.top) { | ||
264 | if (initial.h + dy > min_sane_h && initial.tb.h - dy > min_sane_h) { | ||
265 | initial.ptr->height = initial.h + dy; | ||
266 | initial.tb.ptr->height = initial.tb.h - dy; | ||
267 | initial.tb.ptr->y = initial.tb.y + dy; | ||
268 | } | ||
269 | } else { //lock.bottom | ||
270 | if (initial.h - dy > min_sane_h && initial.tb.h + dy > min_sane_h) { | ||
271 | initial.ptr->height = initial.h - dy; | ||
272 | initial.ptr->y = initial.y + dy; | ||
273 | initial.tb.ptr->height = initial.tb.h + dy; | ||
274 | } | ||
275 | changed = true; | ||
276 | } | ||
277 | arrange_windows(initial.tb.ptr->parent, -1, -1); | ||
278 | } | ||
279 | if (changed) { | ||
280 | arrange_windows(initial.ptr->parent, -1, -1); | ||
281 | } | ||
282 | changed = false; | ||
248 | default: | 283 | default: |
249 | return; | 284 | return; |
250 | } | 285 | } |
251 | if (changed) { | ||
252 | update_geometry(view); | ||
253 | } | ||
254 | } | 286 | } |
255 | 287 | ||
256 | void pointer_mode_reset(void) { | 288 | void pointer_mode_reset(void) { |
257 | switch (pointer_state.mode) { | 289 | switch (pointer_state.mode) { |
258 | case M_FLOATING | M_DRAGGING: | 290 | case M_FLOATING | M_DRAGGING: |
259 | case M_FLOATING | M_RESIZING: | 291 | case M_FLOATING | M_RESIZING: |
260 | pointer_mode_reset_floating(); | 292 | reset_initial_view(); |
261 | break; | 293 | break; |
262 | 294 | ||
263 | case M_TILING | M_DRAGGING: | 295 | case M_TILING | M_DRAGGING: |
@@ -267,27 +299,3 @@ void pointer_mode_reset(void) { | |||
267 | } | 299 | } |
268 | } | 300 | } |
269 | 301 | ||
270 | |||
271 | static struct wlc_geometry saved_floating; | ||
272 | |||
273 | void start_floating(swayc_t *view) { | ||
274 | if (view->is_floating) { | ||
275 | saved_floating.origin.x = view->x; | ||
276 | saved_floating.origin.y = view->y; | ||
277 | saved_floating.size.w = view->width; | ||
278 | saved_floating.size.h = view->height; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | void reset_floating(swayc_t *view) { | ||
283 | if (view->is_floating) { | ||
284 | view->x = saved_floating.origin.x; | ||
285 | view->y = saved_floating.origin.y; | ||
286 | view->width = saved_floating.size.w; | ||
287 | view->height = saved_floating.size.h; | ||
288 | arrange_windows(view->parent, -1, -1); | ||
289 | } | ||
290 | pointer_state.floating = (struct pointer_floating){0, 0}; | ||
291 | pointer_state.lock = (struct pointer_lock){0, 0, 0, 0, 0, 0, 0, 0}; | ||
292 | } | ||
293 | |||