aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/seat.c
diff options
context:
space:
mode:
authorLibravatar Tony Crisci <tony@dubstepdish.com>2018-02-04 13:39:10 -0500
committerLibravatar Tony Crisci <tony@dubstepdish.com>2018-02-04 14:08:54 -0500
commit515150229847c9ebdfd0cabb6f0026fca9d57a23 (patch)
tree8a50ce0ac8ce4dc2ec973c63c68dc45378c50737 /sway/input/seat.c
parentImplement workspaces (diff)
downloadsway-515150229847c9ebdfd0cabb6f0026fca9d57a23.tar.gz
sway-515150229847c9ebdfd0cabb6f0026fca9d57a23.tar.zst
sway-515150229847c9ebdfd0cabb6f0026fca9d57a23.zip
basic focus overhaul
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r--sway/input/seat.c137
1 files changed, 114 insertions, 23 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 5e87986d..cbf05abd 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -32,6 +32,44 @@ void sway_seat_destroy(struct sway_seat *seat) {
32 wlr_seat_destroy(seat->wlr_seat); 32 wlr_seat_destroy(seat->wlr_seat);
33} 33}
34 34
35static void handle_seat_container_destroy(struct wl_listener *listener,
36 void *data) {
37 struct sway_seat_container *seat_con =
38 wl_container_of(listener, seat_con, destroy);
39 wl_list_remove(&seat_con->link);
40 wl_list_remove(&seat_con->destroy.link);
41 free(seat_con);
42}
43
44static struct sway_seat_container *seat_container_from_container(
45 struct sway_seat *seat, swayc_t *con) {
46 struct sway_seat_container *seat_con = NULL;
47 wl_list_for_each(seat_con, &seat->focus_stack, link) {
48 if (seat_con->container == con) {
49 return seat_con;
50 }
51 }
52
53 seat_con = calloc(1, sizeof(struct sway_seat_container));
54 if (seat_con == NULL) {
55 wlr_log(L_ERROR, "could not allocate seat container");
56 return NULL;
57 }
58
59 seat_con->container = con;
60 wl_list_insert(seat->focus_stack.prev, &seat_con->link);
61 wl_signal_add(&con->events.destroy, &seat_con->destroy);
62 seat_con->destroy.notify = handle_seat_container_destroy;
63
64 return seat_con;
65}
66
67static void handle_new_container(struct wl_listener *listener, void *data) {
68 struct sway_seat *seat = wl_container_of(listener, seat, new_container);
69 swayc_t *con = data;
70 seat_container_from_container(seat, con);
71}
72
35struct sway_seat *sway_seat_create(struct sway_input_manager *input, 73struct sway_seat *sway_seat_create(struct sway_input_manager *input,
36 const char *seat_name) { 74 const char *seat_name) {
37 struct sway_seat *seat = calloc(1, sizeof(struct sway_seat)); 75 struct sway_seat *seat = calloc(1, sizeof(struct sway_seat));
@@ -52,6 +90,24 @@ struct sway_seat *sway_seat_create(struct sway_input_manager *input,
52 return NULL; 90 return NULL;
53 } 91 }
54 92
93 // init the focus stack
94 wl_list_init(&seat->focus_stack);
95 list_t *containers = container_list_children(&root_container);
96 if (containers == NULL) {
97 wlr_seat_destroy(seat->wlr_seat);
98 free(seat);
99 return NULL;
100 }
101 for (int i = containers->length - 1; i >= 0; --i) {
102 swayc_t *con = containers->items[i];
103 seat_container_from_container(seat, con);
104 }
105 free(containers);
106
107 wl_signal_add(&root_container.sway_root->events.new_container,
108 &seat->new_container);
109 seat->new_container.notify = handle_new_container;
110
55 seat->input = input; 111 seat->input = input;
56 wl_list_init(&seat->devices); 112 wl_list_init(&seat->devices);
57 113
@@ -82,12 +138,15 @@ static void seat_configure_keyboard(struct sway_seat *seat,
82 sway_keyboard_configure(seat_device->keyboard); 138 sway_keyboard_configure(seat_device->keyboard);
83 wlr_seat_set_keyboard(seat->wlr_seat, 139 wlr_seat_set_keyboard(seat->wlr_seat,
84 seat_device->input_device->wlr_device); 140 seat_device->input_device->wlr_device);
85 if (seat->focus && seat->focus->type == C_VIEW) { 141 if (seat->has_focus) {
86 // force notify reenter to pick up the new configuration 142 swayc_t *focus = sway_seat_get_focus(seat, &root_container);
87 wlr_seat_keyboard_clear_focus(seat->wlr_seat); 143 if (focus && focus->type == C_VIEW) {
88 wlr_seat_keyboard_notify_enter(seat->wlr_seat, 144 // force notify reenter to pick up the new configuration
89 seat->focus->sway_view->surface, wlr_keyboard->keycodes, 145 wlr_seat_keyboard_clear_focus(seat->wlr_seat);
90 wlr_keyboard->num_keycodes, &wlr_keyboard->modifiers); 146 wlr_seat_keyboard_notify_enter(seat->wlr_seat,
147 focus->sway_view->surface, wlr_keyboard->keycodes,
148 wlr_keyboard->num_keycodes, &wlr_keyboard->modifiers);
149 }
91 } 150 }
92} 151}
93 152
@@ -211,35 +270,43 @@ static void handle_focus_destroy(struct wl_listener *listener, void *data) {
211} 270}
212 271
213void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) { 272void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) {
214 swayc_t *last_focus = seat->focus; 273 swayc_t *last_focus =
274 (seat->has_focus ? sway_seat_get_focus(seat, &root_container) : NULL);
215 275
216 if (last_focus == container) { 276 if (container && last_focus == container) {
217 return; 277 return;
218 } 278 }
219 279
220 if (last_focus && last_focus->type == C_VIEW) { 280 if (last_focus) {
221 wl_list_remove(&seat->focus_destroy.link); 281 wl_list_remove(&seat->focus_destroy.link);
282 seat->has_focus = false;
222 } 283 }
223 284
224 if (container && container->type == C_VIEW) { 285 if (container) {
225 struct sway_view *view = container->sway_view; 286 struct sway_seat_container *seat_con =
226 view_set_activated(view, true); 287 seat_container_from_container(seat, container);
227 wl_signal_add(&container->events.destroy, &seat->focus_destroy); 288 wl_signal_add(&container->events.destroy, &seat->focus_destroy);
228 seat->focus_destroy.notify = handle_focus_destroy; 289 seat->focus_destroy.notify = handle_focus_destroy;
229 290 seat->has_focus = true;
230 struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); 291
231 if (keyboard) { 292 wl_list_remove(&seat_con->link);
232 wlr_seat_keyboard_notify_enter(seat->wlr_seat, view->surface, 293 wl_list_insert(&seat->focus_stack, &seat_con->link);
233 keyboard->keycodes, keyboard->num_keycodes, 294
234 &keyboard->modifiers); 295 if (container->type == C_VIEW) {
235 } else { 296 struct sway_view *view = container->sway_view;
236 wlr_seat_keyboard_notify_enter(seat->wlr_seat, view->surface, 297 view_set_activated(view, true);
237 NULL, 0, NULL); 298 struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
299 if (keyboard) {
300 wlr_seat_keyboard_notify_enter(seat->wlr_seat, view->surface,
301 keyboard->keycodes, keyboard->num_keycodes,
302 &keyboard->modifiers);
303 } else {
304 wlr_seat_keyboard_notify_enter(seat->wlr_seat, view->surface,
305 NULL, 0, NULL);
306 }
238 } 307 }
239 } 308 }
240 309
241 seat->focus = container;
242
243 if (last_focus && last_focus->type == C_VIEW && 310 if (last_focus && last_focus->type == C_VIEW &&
244 !sway_input_manager_has_focus(seat->input, last_focus)) { 311 !sway_input_manager_has_focus(seat->input, last_focus)) {
245 struct sway_view *view = last_focus->sway_view; 312 struct sway_view *view = last_focus->sway_view;
@@ -247,6 +314,30 @@ void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) {
247 } 314 }
248} 315}
249 316
317swayc_t *sway_seat_get_focus(struct sway_seat *seat, swayc_t *container) {
318 struct sway_seat_container *current = NULL;
319 swayc_t *parent = NULL;
320 wl_list_for_each(current, &seat->focus_stack, link) {
321 if (current->container->type < C_WORKSPACE) {
322 continue;
323 }
324 parent = current->container->parent;
325
326 if (current->container == container) {
327 return current->container;
328 }
329
330 while (parent) {
331 if (parent == container) {
332 return current->container;
333 }
334 parent = parent->parent;
335 }
336 }
337
338 return NULL;
339}
340
250void sway_seat_set_config(struct sway_seat *seat, 341void sway_seat_set_config(struct sway_seat *seat,
251 struct seat_config *seat_config) { 342 struct seat_config *seat_config) {
252 // clear configs 343 // clear configs