diff options
author | Tony Crisci <tony@dubstepdish.com> | 2018-04-02 16:09:27 -0400 |
---|---|---|
committer | Tony Crisci <tony@dubstepdish.com> | 2018-04-02 16:09:27 -0400 |
commit | d434da563239c43c5fe417ce83b23b417f2ab635 (patch) | |
tree | e154daaf43c42d11c5afb8b7739ae6b52dd01215 | |
parent | fix workspace splits (diff) | |
parent | Merge pull request #1699 from acrisci/seat-fixes (diff) | |
download | sway-d434da563239c43c5fe417ce83b23b417f2ab635.tar.gz sway-d434da563239c43c5fe417ce83b23b417f2ab635.tar.zst sway-d434da563239c43c5fe417ce83b23b417f2ab635.zip |
Merge branch 'wlroots' into split-containers
32 files changed, 803 insertions, 240 deletions
diff --git a/common/pango.c b/common/pango.c index 2ae7883c..658d2876 100644 --- a/common/pango.c +++ b/common/pango.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <stdio.h> | 6 | #include <stdio.h> |
7 | #include <stdlib.h> | 7 | #include <stdlib.h> |
8 | #include <string.h> | 8 | #include <string.h> |
9 | #include "log.h" | ||
9 | 10 | ||
10 | PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, | 11 | PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, |
11 | const char *text, int32_t scale, bool markup) { | 12 | const char *text, int32_t scale, bool markup) { |
@@ -13,7 +14,13 @@ PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, | |||
13 | PangoAttrList *attrs; | 14 | PangoAttrList *attrs; |
14 | if (markup) { | 15 | if (markup) { |
15 | char *buf; | 16 | char *buf; |
16 | pango_parse_markup(text, -1, 0, &attrs, &buf, NULL, NULL); | 17 | GError *error = NULL; |
18 | if (!sway_assert(pango_parse_markup( | ||
19 | text, -1, 0, &attrs, &buf, NULL, &error), | ||
20 | "pango_parse_markup '%s' -> error %s", text, | ||
21 | error ? error->message : NULL)) { | ||
22 | return NULL; | ||
23 | } | ||
17 | pango_layout_set_markup(layout, buf, -1); | 24 | pango_layout_set_markup(layout, buf, -1); |
18 | free(buf); | 25 | free(buf); |
19 | } else { | 26 | } else { |
diff --git a/include/sway/config.h b/include/sway/config.h index 03b51948..91f772b5 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -377,6 +377,7 @@ void free_config(struct sway_config *config); | |||
377 | void config_clear_handler_context(struct sway_config *config); | 377 | void config_clear_handler_context(struct sway_config *config); |
378 | 378 | ||
379 | void free_sway_variable(struct sway_variable *var); | 379 | void free_sway_variable(struct sway_variable *var); |
380 | |||
380 | /** | 381 | /** |
381 | * Does variable replacement for a string based on the config's currently loaded variables. | 382 | * Does variable replacement for a string based on the config's currently loaded variables. |
382 | */ | 383 | */ |
@@ -385,44 +386,68 @@ char *do_var_replacement(char *str); | |||
385 | struct cmd_results *check_security_config(); | 386 | struct cmd_results *check_security_config(); |
386 | 387 | ||
387 | int input_identifier_cmp(const void *item, const void *data); | 388 | int input_identifier_cmp(const void *item, const void *data); |
389 | |||
388 | struct input_config *new_input_config(const char* identifier); | 390 | struct input_config *new_input_config(const char* identifier); |
391 | |||
389 | void merge_input_config(struct input_config *dst, struct input_config *src); | 392 | void merge_input_config(struct input_config *dst, struct input_config *src); |
393 | |||
390 | struct input_config *copy_input_config(struct input_config *ic); | 394 | struct input_config *copy_input_config(struct input_config *ic); |
395 | |||
391 | void free_input_config(struct input_config *ic); | 396 | void free_input_config(struct input_config *ic); |
397 | |||
392 | void apply_input_config(struct input_config *input); | 398 | void apply_input_config(struct input_config *input); |
393 | 399 | ||
394 | int seat_name_cmp(const void *item, const void *data); | 400 | int seat_name_cmp(const void *item, const void *data); |
401 | |||
395 | struct seat_config *new_seat_config(const char* name); | 402 | struct seat_config *new_seat_config(const char* name); |
403 | |||
396 | void merge_seat_config(struct seat_config *dst, struct seat_config *src); | 404 | void merge_seat_config(struct seat_config *dst, struct seat_config *src); |
405 | |||
397 | struct seat_config *copy_seat_config(struct seat_config *seat); | 406 | struct seat_config *copy_seat_config(struct seat_config *seat); |
407 | |||
398 | void free_seat_config(struct seat_config *ic); | 408 | void free_seat_config(struct seat_config *ic); |
409 | |||
399 | struct seat_attachment_config *seat_attachment_config_new(); | 410 | struct seat_attachment_config *seat_attachment_config_new(); |
411 | |||
400 | struct seat_attachment_config *seat_config_get_attachment( | 412 | struct seat_attachment_config *seat_config_get_attachment( |
401 | struct seat_config *seat_config, char *identifier); | 413 | struct seat_config *seat_config, char *identifier); |
414 | |||
402 | void apply_seat_config(struct seat_config *seat); | 415 | void apply_seat_config(struct seat_config *seat); |
403 | 416 | ||
404 | int output_name_cmp(const void *item, const void *data); | 417 | int output_name_cmp(const void *item, const void *data); |
418 | |||
405 | void output_get_identifier(char *identifier, size_t len, | 419 | void output_get_identifier(char *identifier, size_t len, |
406 | struct sway_output *output); | 420 | struct sway_output *output); |
421 | |||
407 | struct output_config *new_output_config(const char *name); | 422 | struct output_config *new_output_config(const char *name); |
423 | |||
408 | void merge_output_config(struct output_config *dst, struct output_config *src); | 424 | void merge_output_config(struct output_config *dst, struct output_config *src); |
425 | |||
409 | void apply_output_config(struct output_config *oc, | 426 | void apply_output_config(struct output_config *oc, |
410 | struct sway_container *output); | 427 | struct sway_container *output); |
428 | |||
411 | void free_output_config(struct output_config *oc); | 429 | void free_output_config(struct output_config *oc); |
412 | 430 | ||
413 | int workspace_output_cmp_workspace(const void *a, const void *b); | 431 | int workspace_output_cmp_workspace(const void *a, const void *b); |
414 | 432 | ||
415 | int sway_binding_cmp(const void *a, const void *b); | 433 | int sway_binding_cmp(const void *a, const void *b); |
434 | |||
416 | int sway_binding_cmp_qsort(const void *a, const void *b); | 435 | int sway_binding_cmp_qsort(const void *a, const void *b); |
436 | |||
417 | int sway_binding_cmp_keys(const void *a, const void *b); | 437 | int sway_binding_cmp_keys(const void *a, const void *b); |
438 | |||
418 | void free_sway_binding(struct sway_binding *sb); | 439 | void free_sway_binding(struct sway_binding *sb); |
440 | |||
419 | struct sway_binding *sway_binding_dup(struct sway_binding *sb); | 441 | struct sway_binding *sway_binding_dup(struct sway_binding *sb); |
420 | 442 | ||
421 | /* Bar stuff */ | ||
422 | void load_swaybars(); | 443 | void load_swaybars(); |
444 | |||
423 | void invoke_swaybar(struct bar_config *bar); | 445 | void invoke_swaybar(struct bar_config *bar); |
446 | |||
424 | void terminate_swaybg(pid_t pid); | 447 | void terminate_swaybg(pid_t pid); |
448 | |||
425 | struct bar_config *default_bar_config(void); | 449 | struct bar_config *default_bar_config(void); |
450 | |||
426 | void free_bar_config(struct bar_config *bar); | 451 | void free_bar_config(struct bar_config *bar); |
427 | 452 | ||
428 | /* Global config singleton. */ | 453 | /* Global config singleton. */ |
diff --git a/include/sway/input/input-manager.h b/include/sway/input/input-manager.h index c6c73dba..8e39a4a7 100644 --- a/include/sway/input/input-manager.h +++ b/include/sway/input/input-manager.h | |||
@@ -14,7 +14,6 @@ extern struct sway_input_manager *input_manager; | |||
14 | struct sway_input_device { | 14 | struct sway_input_device { |
15 | char *identifier; | 15 | char *identifier; |
16 | struct wlr_input_device *wlr_device; | 16 | struct wlr_input_device *wlr_device; |
17 | struct input_config *config; | ||
18 | struct wl_list link; | 17 | struct wl_list link; |
19 | struct wl_listener device_destroy; | 18 | struct wl_listener device_destroy; |
20 | }; | 19 | }; |
@@ -27,30 +26,34 @@ struct sway_input_manager { | |||
27 | struct wl_listener new_input; | 26 | struct wl_listener new_input; |
28 | }; | 27 | }; |
29 | 28 | ||
30 | struct sway_input_manager *sway_input_manager_create( | 29 | struct sway_input_manager *input_manager_create(struct sway_server *server); |
31 | struct sway_server *server); | ||
32 | 30 | ||
33 | bool sway_input_manager_has_focus(struct sway_input_manager *input, | 31 | bool input_manager_has_focus(struct sway_input_manager *input, |
34 | struct sway_container *container); | 32 | struct sway_container *container); |
35 | 33 | ||
36 | void sway_input_manager_set_focus(struct sway_input_manager *input, | 34 | void input_manager_set_focus(struct sway_input_manager *input, |
37 | struct sway_container *container); | 35 | struct sway_container *container); |
38 | 36 | ||
39 | void sway_input_manager_configure_xcursor(struct sway_input_manager *input); | 37 | void input_manager_configure_xcursor(struct sway_input_manager *input); |
40 | 38 | ||
41 | void sway_input_manager_apply_input_config(struct sway_input_manager *input, | 39 | void input_manager_apply_input_config(struct sway_input_manager *input, |
42 | struct input_config *input_config); | 40 | struct input_config *input_config); |
43 | 41 | ||
44 | void sway_input_manager_apply_seat_config(struct sway_input_manager *input, | 42 | void input_manager_apply_seat_config(struct sway_input_manager *input, |
45 | struct seat_config *seat_config); | 43 | struct seat_config *seat_config); |
46 | 44 | ||
47 | struct sway_seat *sway_input_manager_get_default_seat( | 45 | struct sway_seat *input_manager_get_default_seat( |
48 | struct sway_input_manager *input); | 46 | struct sway_input_manager *input); |
49 | 47 | ||
50 | struct sway_seat *input_manager_get_seat(struct sway_input_manager *input, | 48 | struct sway_seat *input_manager_get_seat(struct sway_input_manager *input, |
51 | const char *seat_name); | 49 | const char *seat_name); |
52 | 50 | ||
53 | /** Gets the last seat the user interacted with */ | 51 | /** |
52 | * Gets the last seat the user interacted with | ||
53 | */ | ||
54 | struct sway_seat *input_manager_current_seat(struct sway_input_manager *input); | 54 | struct sway_seat *input_manager_current_seat(struct sway_input_manager *input); |
55 | 55 | ||
56 | struct input_config *input_device_get_config(struct sway_input_device *device); | ||
57 | |||
58 | |||
56 | #endif | 59 | #endif |
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index 38795e14..c780a52b 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h | |||
@@ -8,7 +8,6 @@ struct sway_seat_device { | |||
8 | struct sway_seat *sway_seat; | 8 | struct sway_seat *sway_seat; |
9 | struct sway_input_device *input_device; | 9 | struct sway_input_device *input_device; |
10 | struct sway_keyboard *keyboard; | 10 | struct sway_keyboard *keyboard; |
11 | struct seat_attachment_config *attachment_config; | ||
12 | struct wl_list link; // sway_seat::devices | 11 | struct wl_list link; // sway_seat::devices |
13 | }; | 12 | }; |
14 | 13 | ||
@@ -23,7 +22,6 @@ struct sway_seat_container { | |||
23 | 22 | ||
24 | struct sway_seat { | 23 | struct sway_seat { |
25 | struct wlr_seat *wlr_seat; | 24 | struct wlr_seat *wlr_seat; |
26 | struct seat_config *config; | ||
27 | struct sway_cursor *cursor; | 25 | struct sway_cursor *cursor; |
28 | struct sway_input_manager *input; | 26 | struct sway_input_manager *input; |
29 | 27 | ||
@@ -38,28 +36,28 @@ struct sway_seat { | |||
38 | struct wl_list link; // input_manager::seats | 36 | struct wl_list link; // input_manager::seats |
39 | }; | 37 | }; |
40 | 38 | ||
41 | struct sway_seat *sway_seat_create(struct sway_input_manager *input, | 39 | struct sway_seat *seat_create(struct sway_input_manager *input, |
42 | const char *seat_name); | 40 | const char *seat_name); |
43 | 41 | ||
44 | void sway_seat_destroy(struct sway_seat *seat); | 42 | void seat_destroy(struct sway_seat *seat); |
45 | 43 | ||
46 | void sway_seat_add_device(struct sway_seat *seat, | 44 | void seat_add_device(struct sway_seat *seat, |
47 | struct sway_input_device *device); | 45 | struct sway_input_device *device); |
48 | 46 | ||
49 | void sway_seat_configure_device(struct sway_seat *seat, | 47 | void seat_configure_device(struct sway_seat *seat, |
50 | struct sway_input_device *device); | 48 | struct sway_input_device *device); |
51 | 49 | ||
52 | void sway_seat_remove_device(struct sway_seat *seat, | 50 | void seat_remove_device(struct sway_seat *seat, |
53 | struct sway_input_device *device); | 51 | struct sway_input_device *device); |
54 | 52 | ||
55 | void sway_seat_configure_xcursor(struct sway_seat *seat); | 53 | void seat_configure_xcursor(struct sway_seat *seat); |
56 | 54 | ||
57 | void sway_seat_set_focus(struct sway_seat *seat, struct sway_container *container); | 55 | void seat_set_focus(struct sway_seat *seat, struct sway_container *container); |
58 | 56 | ||
59 | void sway_seat_set_focus_warp(struct sway_seat *seat, | 57 | void seat_set_focus_warp(struct sway_seat *seat, |
60 | struct sway_container *container, bool warp); | 58 | struct sway_container *container, bool warp); |
61 | 59 | ||
62 | struct sway_container *sway_seat_get_focus(struct sway_seat *seat); | 60 | struct sway_container *seat_get_focus(struct sway_seat *seat); |
63 | 61 | ||
64 | /** | 62 | /** |
65 | * Return the last container to be focused for the seat (or the most recently | 63 | * Return the last container to be focused for the seat (or the most recently |
@@ -70,12 +68,14 @@ struct sway_container *sway_seat_get_focus(struct sway_seat *seat); | |||
70 | * is destroyed, or focus moves to a container with children and we need to | 68 | * is destroyed, or focus moves to a container with children and we need to |
71 | * descend into the next leaf in focus order. | 69 | * descend into the next leaf in focus order. |
72 | */ | 70 | */ |
73 | struct sway_container *sway_seat_get_focus_inactive(struct sway_seat *seat, | 71 | struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, |
74 | struct sway_container *container); | 72 | struct sway_container *container); |
75 | 73 | ||
76 | struct sway_container *sway_seat_get_focus_by_type(struct sway_seat *seat, | 74 | struct sway_container *seat_get_focus_by_type(struct sway_seat *seat, |
77 | struct sway_container *container, enum sway_container_type type); | 75 | struct sway_container *container, enum sway_container_type type); |
78 | 76 | ||
79 | void sway_seat_set_config(struct sway_seat *seat, struct seat_config *seat_config); | 77 | void seat_apply_config(struct sway_seat *seat, struct seat_config *seat_config); |
78 | |||
79 | struct seat_config *seat_get_config(struct sway_seat *seat); | ||
80 | 80 | ||
81 | #endif | 81 | #endif |
diff --git a/include/swaybar/ipc.h b/include/swaybar/ipc.h index 6ea7c4d6..a1696bcf 100644 --- a/include/swaybar/ipc.h +++ b/include/swaybar/ipc.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include "swaybar/bar.h" | 4 | #include "swaybar/bar.h" |
5 | 5 | ||
6 | void ipc_initialize(struct swaybar *bar, const char *bar_id); | 6 | void ipc_initialize(struct swaybar *bar, const char *bar_id); |
7 | bool handle_ipc_event(struct swaybar *bar); | 7 | bool handle_ipc_readable(struct swaybar *bar); |
8 | void ipc_get_workspaces(struct swaybar *bar); | 8 | void ipc_get_workspaces(struct swaybar *bar); |
9 | void ipc_send_workspace_command(struct swaybar *bar, const char *ws); | 9 | void ipc_send_workspace_command(struct swaybar *bar, const char *ws); |
10 | 10 | ||
diff --git a/include/swaybar/status_line.h b/include/swaybar/status_line.h index 6c595df0..3538f49c 100644 --- a/include/swaybar/status_line.h +++ b/include/swaybar/status_line.h | |||
@@ -7,10 +7,52 @@ | |||
7 | 7 | ||
8 | enum status_protocol { | 8 | enum status_protocol { |
9 | PROTOCOL_UNDEF, | 9 | PROTOCOL_UNDEF, |
10 | PROTOCOL_ERROR, | ||
10 | PROTOCOL_TEXT, | 11 | PROTOCOL_TEXT, |
11 | PROTOCOL_I3BAR, | 12 | PROTOCOL_I3BAR, |
12 | }; | 13 | }; |
13 | 14 | ||
15 | struct text_protocol_state { | ||
16 | char *buffer; | ||
17 | size_t buffer_size; | ||
18 | }; | ||
19 | |||
20 | enum json_node_type { | ||
21 | JSON_NODE_UNKNOWN, | ||
22 | JSON_NODE_ARRAY, | ||
23 | JSON_NODE_STRING, | ||
24 | }; | ||
25 | |||
26 | struct i3bar_protocol_state { | ||
27 | bool click_events; | ||
28 | char *buffer; | ||
29 | size_t buffer_size; | ||
30 | size_t buffer_index; | ||
31 | const char *current_node; | ||
32 | bool escape; | ||
33 | size_t depth; | ||
34 | enum json_node_type nodes[16]; | ||
35 | }; | ||
36 | |||
37 | struct i3bar_block { | ||
38 | struct wl_list link; | ||
39 | char *full_text, *short_text, *align; | ||
40 | bool urgent; | ||
41 | uint32_t *color; | ||
42 | int min_width; | ||
43 | char *name, *instance; | ||
44 | bool separator; | ||
45 | int separator_block_width; | ||
46 | bool markup; | ||
47 | // Airblader features | ||
48 | uint32_t background; | ||
49 | uint32_t border; | ||
50 | int border_top; | ||
51 | int border_bottom; | ||
52 | int border_left; | ||
53 | int border_right; | ||
54 | }; | ||
55 | |||
14 | struct status_line { | 56 | struct status_line { |
15 | pid_t pid; | 57 | pid_t pid; |
16 | int read_fd, write_fd; | 58 | int read_fd, write_fd; |
@@ -18,13 +60,18 @@ struct status_line { | |||
18 | 60 | ||
19 | enum status_protocol protocol; | 61 | enum status_protocol protocol; |
20 | const char *text; | 62 | const char *text; |
63 | struct wl_list blocks; // i3bar_block::link | ||
21 | 64 | ||
22 | char *buffer; | 65 | struct text_protocol_state text_state; |
23 | size_t buffer_size; | 66 | struct i3bar_protocol_state i3bar_state; |
24 | }; | 67 | }; |
25 | 68 | ||
26 | struct status_line *status_line_init(char *cmd); | 69 | struct status_line *status_line_init(char *cmd); |
70 | void status_error(struct status_line *status, const char *text); | ||
71 | bool status_handle_readable(struct status_line *status); | ||
27 | void status_line_free(struct status_line *status); | 72 | void status_line_free(struct status_line *status); |
28 | bool handle_status_readable(struct status_line *status); | 73 | bool i3bar_handle_readable(struct status_line *status); |
74 | void i3bar_block_send_click(struct status_line *status, | ||
75 | struct i3bar_block *block, int x, int y, uint32_t button); | ||
29 | 76 | ||
30 | #endif | 77 | #endif |
diff --git a/sway/commands.c b/sway/commands.c index 90012c6d..8156a08e 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -72,23 +72,23 @@ void apply_input_config(struct input_config *input) { | |||
72 | list_add(config->input_configs, input); | 72 | list_add(config->input_configs, input); |
73 | } | 73 | } |
74 | 74 | ||
75 | sway_input_manager_apply_input_config(input_manager, input); | 75 | input_manager_apply_input_config(input_manager, input); |
76 | } | 76 | } |
77 | 77 | ||
78 | void apply_seat_config(struct seat_config *seat) { | 78 | void apply_seat_config(struct seat_config *seat_config) { |
79 | int i; | 79 | int i; |
80 | i = list_seq_find(config->seat_configs, seat_name_cmp, seat->name); | 80 | i = list_seq_find(config->seat_configs, seat_name_cmp, seat_config->name); |
81 | if (i >= 0) { | 81 | if (i >= 0) { |
82 | // merge existing config | 82 | // merge existing config |
83 | struct seat_config *sc = config->seat_configs->items[i]; | 83 | struct seat_config *sc = config->seat_configs->items[i]; |
84 | merge_seat_config(sc, seat); | 84 | merge_seat_config(sc, seat_config); |
85 | free_seat_config(seat); | 85 | free_seat_config(seat_config); |
86 | seat = sc; | 86 | seat_config = sc; |
87 | } else { | 87 | } else { |
88 | list_add(config->seat_configs, seat); | 88 | list_add(config->seat_configs, seat_config); |
89 | } | 89 | } |
90 | 90 | ||
91 | sway_input_manager_apply_seat_config(input_manager, seat); | 91 | input_manager_apply_seat_config(input_manager, seat_config); |
92 | } | 92 | } |
93 | 93 | ||
94 | /* Keep alphabetized */ | 94 | /* Keep alphabetized */ |
@@ -267,7 +267,7 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) { | |||
267 | 267 | ||
268 | if (seat == NULL) { | 268 | if (seat == NULL) { |
269 | // passing a NULL seat means we just pick the default seat | 269 | // passing a NULL seat means we just pick the default seat |
270 | seat = sway_input_manager_get_default_seat(input_manager); | 270 | seat = input_manager_get_default_seat(input_manager); |
271 | if (!sway_assert(seat, "could not find a seat to run the command on")) { | 271 | if (!sway_assert(seat, "could not find a seat to run the command on")) { |
272 | return NULL; | 272 | return NULL; |
273 | } | 273 | } |
@@ -345,7 +345,7 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) { | |||
345 | // without criteria, the command acts upon the focused | 345 | // without criteria, the command acts upon the focused |
346 | // container | 346 | // container |
347 | config->handler_context.current_container = | 347 | config->handler_context.current_container = |
348 | sway_seat_get_focus_inactive(seat, &root_container); | 348 | seat_get_focus_inactive(seat, &root_container); |
349 | if (!sway_assert(config->handler_context.current_container, | 349 | if (!sway_assert(config->handler_context.current_container, |
350 | "could not get focus-inactive for root container")) { | 350 | "could not get focus-inactive for root container")) { |
351 | return NULL; | 351 | return NULL; |
diff --git a/sway/commands/focus.c b/sway/commands/focus.c index 0a521b9e..74d9d535 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c | |||
@@ -36,7 +36,7 @@ struct cmd_results *cmd_focus(int argc, char **argv) { | |||
36 | } | 36 | } |
37 | 37 | ||
38 | if (argc == 0) { | 38 | if (argc == 0) { |
39 | sway_seat_set_focus(seat, con); | 39 | seat_set_focus(seat, con); |
40 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 40 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
41 | } | 41 | } |
42 | 42 | ||
@@ -50,7 +50,7 @@ struct cmd_results *cmd_focus(int argc, char **argv) { | |||
50 | struct sway_container *next_focus = container_get_in_direction( | 50 | struct sway_container *next_focus = container_get_in_direction( |
51 | con, seat, direction); | 51 | con, seat, direction); |
52 | if (next_focus) { | 52 | if (next_focus) { |
53 | sway_seat_set_focus(seat, next_focus); | 53 | seat_set_focus(seat, next_focus); |
54 | } | 54 | } |
55 | 55 | ||
56 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 56 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/move.c b/sway/commands/move.c index ab959b77..644c622b 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -78,10 +78,10 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, | |||
78 | } | 78 | } |
79 | free(ws_name); | 79 | free(ws_name); |
80 | struct sway_container *old_parent = current->parent; | 80 | struct sway_container *old_parent = current->parent; |
81 | struct sway_container *focus = sway_seat_get_focus_inactive( | 81 | struct sway_container *focus = seat_get_focus_inactive( |
82 | config->handler_context.seat, ws); | 82 | config->handler_context.seat, ws); |
83 | container_move_to(current, focus); | 83 | container_move_to(current, focus); |
84 | sway_seat_set_focus(config->handler_context.seat, old_parent); | 84 | seat_set_focus(config->handler_context.seat, old_parent); |
85 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 85 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
86 | } else if (strcasecmp(argv[1], "to") == 0 | 86 | } else if (strcasecmp(argv[1], "to") == 0 |
87 | && strcasecmp(argv[2], "output") == 0) { | 87 | && strcasecmp(argv[2], "output") == 0) { |
@@ -100,7 +100,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, | |||
100 | return cmd_results_new(CMD_FAILURE, "move workspace", | 100 | return cmd_results_new(CMD_FAILURE, "move workspace", |
101 | "Can't find output with name/direction '%s'", argv[3]); | 101 | "Can't find output with name/direction '%s'", argv[3]); |
102 | } | 102 | } |
103 | struct sway_container *focus = sway_seat_get_focus_inactive( | 103 | struct sway_container *focus = seat_get_focus_inactive( |
104 | config->handler_context.seat, destination); | 104 | config->handler_context.seat, destination); |
105 | if (!focus) { | 105 | if (!focus) { |
106 | // We've never been to this output before | 106 | // We've never been to this output before |
@@ -108,7 +108,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, | |||
108 | } | 108 | } |
109 | struct sway_container *old_parent = current->parent; | 109 | struct sway_container *old_parent = current->parent; |
110 | container_move_to(current, focus); | 110 | container_move_to(current, focus); |
111 | sway_seat_set_focus(config->handler_context.seat, old_parent); | 111 | seat_set_focus(config->handler_context.seat, old_parent); |
112 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 112 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
113 | } | 113 | } |
114 | return cmd_results_new(CMD_INVALID, "move", expected_syntax); | 114 | return cmd_results_new(CMD_INVALID, "move", expected_syntax); |
diff --git a/sway/commands/seat.c b/sway/commands/seat.c index 45079616..819b769c 100644 --- a/sway/commands/seat.c +++ b/sway/commands/seat.c | |||
@@ -14,7 +14,8 @@ struct cmd_results *cmd_seat(int argc, char **argv) { | |||
14 | free_seat_config(config->handler_context.seat_config); | 14 | free_seat_config(config->handler_context.seat_config); |
15 | config->handler_context.seat_config = new_seat_config(argv[0]); | 15 | config->handler_context.seat_config = new_seat_config(argv[0]); |
16 | if (!config->handler_context.seat_config) { | 16 | if (!config->handler_context.seat_config) { |
17 | return cmd_results_new(CMD_FAILURE, NULL, "Couldn't allocate config"); | 17 | return cmd_results_new(CMD_FAILURE, NULL, |
18 | "Couldn't allocate config"); | ||
18 | } | 19 | } |
19 | wlr_log(L_DEBUG, "entering seat block: %s", argv[0]); | 20 | wlr_log(L_DEBUG, "entering seat block: %s", argv[0]); |
20 | return cmd_results_new(CMD_BLOCK_SEAT, NULL, NULL); | 21 | return cmd_results_new(CMD_BLOCK_SEAT, NULL, NULL); |
@@ -28,7 +29,8 @@ struct cmd_results *cmd_seat(int argc, char **argv) { | |||
28 | if (!has_context) { | 29 | if (!has_context) { |
29 | config->handler_context.seat_config = new_seat_config(argv[0]); | 30 | config->handler_context.seat_config = new_seat_config(argv[0]); |
30 | if (!config->handler_context.seat_config) { | 31 | if (!config->handler_context.seat_config) { |
31 | return cmd_results_new(CMD_FAILURE, NULL, "Couldn't allocate config"); | 32 | return cmd_results_new(CMD_FAILURE, NULL, |
33 | "Couldn't allocate config"); | ||
32 | } | 34 | } |
33 | } | 35 | } |
34 | 36 | ||
@@ -41,7 +43,10 @@ struct cmd_results *cmd_seat(int argc, char **argv) { | |||
41 | } else if (strcasecmp("fallback", argv[1]) == 0) { | 43 | } else if (strcasecmp("fallback", argv[1]) == 0) { |
42 | res = seat_cmd_fallback(argc_new, argv_new); | 44 | res = seat_cmd_fallback(argc_new, argv_new); |
43 | } else { | 45 | } else { |
44 | res = cmd_results_new(CMD_INVALID, "seat <name>", "Unknown command %s", argv[1]); | 46 | res = |
47 | cmd_results_new(CMD_INVALID, | ||
48 | "seat <name>", "Unknown command %s", | ||
49 | argv[1]); | ||
45 | } | 50 | } |
46 | 51 | ||
47 | if (!has_context) { | 52 | if (!has_context) { |
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index 8f39e5fc..aa4096f7 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c | |||
@@ -91,7 +91,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { | |||
91 | } | 91 | } |
92 | workspace_switch(ws); | 92 | workspace_switch(ws); |
93 | current_container = | 93 | current_container = |
94 | sway_seat_get_focus(config->handler_context.seat); | 94 | seat_get_focus(config->handler_context.seat); |
95 | struct sway_container *new_output = container_parent(current_container, C_OUTPUT); | 95 | struct sway_container *new_output = container_parent(current_container, C_OUTPUT); |
96 | 96 | ||
97 | if (config->mouse_warping && old_output != new_output) { | 97 | if (config->mouse_warping && old_output != new_output) { |
diff --git a/sway/config.c b/sway/config.c index 0eecf7f6..90b833ab 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -125,7 +125,7 @@ static void destroy_removed_seats(struct sway_config *old_config, | |||
125 | seat_name_cmp, seat_config->name) < 0) { | 125 | seat_name_cmp, seat_config->name) < 0) { |
126 | seat = input_manager_get_seat(input_manager, | 126 | seat = input_manager_get_seat(input_manager, |
127 | seat_config->name); | 127 | seat_config->name); |
128 | sway_seat_destroy(seat); | 128 | seat_destroy(seat); |
129 | } | 129 | } |
130 | } | 130 | } |
131 | } | 131 | } |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index c4265818..5e8a081c 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -228,7 +228,7 @@ static void render_output(struct sway_output *output, struct timespec *when, | |||
228 | 228 | ||
229 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 229 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
230 | struct sway_container *focus = | 230 | struct sway_container *focus = |
231 | sway_seat_get_focus_inactive(seat, output->swayc); | 231 | seat_get_focus_inactive(seat, output->swayc); |
232 | if (!focus) { | 232 | if (!focus) { |
233 | // We've never been to this output before | 233 | // We've never been to this output before |
234 | focus = output->swayc->children->items[0]; | 234 | focus = output->swayc->children->items[0]; |
@@ -373,7 +373,7 @@ void handle_new_output(struct wl_listener *listener, void *data) { | |||
373 | wl_list_init(&output->layers[i]); | 373 | wl_list_init(&output->layers[i]); |
374 | } | 374 | } |
375 | 375 | ||
376 | sway_input_manager_configure_xcursor(input_manager); | 376 | input_manager_configure_xcursor(input_manager); |
377 | 377 | ||
378 | wl_signal_add(&wlr_output->events.destroy, &output->destroy); | 378 | wl_signal_add(&wlr_output->events.destroy, &output->destroy); |
379 | output->destroy.notify = handle_destroy; | 379 | output->destroy.notify = handle_destroy; |
diff --git a/sway/desktop/wl_shell.c b/sway/desktop/wl_shell.c index 4fcc6317..c44fcf27 100644 --- a/sway/desktop/wl_shell.c +++ b/sway/desktop/wl_shell.c | |||
@@ -133,10 +133,10 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { | |||
133 | wl_signal_add(&shell_surface->events.destroy, &sway_surface->destroy); | 133 | wl_signal_add(&shell_surface->events.destroy, &sway_surface->destroy); |
134 | 134 | ||
135 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 135 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
136 | struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); | 136 | struct sway_container *focus = seat_get_focus_inactive(seat, &root_container); |
137 | struct sway_container *cont = container_view_create(focus, sway_view); | 137 | struct sway_container *cont = container_view_create(focus, sway_view); |
138 | sway_view->swayc = cont; | 138 | sway_view->swayc = cont; |
139 | 139 | ||
140 | arrange_windows(cont->parent, -1, -1); | 140 | arrange_windows(cont->parent, -1, -1); |
141 | sway_input_manager_set_focus(input_manager, cont); | 141 | input_manager_set_focus(input_manager, cont); |
142 | } | 142 | } |
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 713437f2..cffe83fb 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -98,11 +98,11 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
98 | container_view_destroy(view->swayc); | 98 | container_view_destroy(view->swayc); |
99 | 99 | ||
100 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 100 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
101 | struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); | 101 | struct sway_container *focus = seat_get_focus_inactive(seat, &root_container); |
102 | struct sway_container *cont = container_view_create(focus, view); | 102 | struct sway_container *cont = container_view_create(focus, view); |
103 | view->swayc = cont; | 103 | view->swayc = cont; |
104 | arrange_windows(cont->parent, -1, -1); | 104 | arrange_windows(cont->parent, -1, -1); |
105 | sway_input_manager_set_focus(input_manager, cont); | 105 | input_manager_set_focus(input_manager, cont); |
106 | 106 | ||
107 | view_damage_whole(sway_surface->view); | 107 | view_damage_whole(sway_surface->view); |
108 | } | 108 | } |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 273ca2bf..17f827d9 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -143,12 +143,12 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
143 | wlr_xwayland_surface_set_maximized(xsurface, true); | 143 | wlr_xwayland_surface_set_maximized(xsurface, true); |
144 | 144 | ||
145 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 145 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
146 | struct sway_container *focus = sway_seat_get_focus_inactive(seat, | 146 | struct sway_container *focus = seat_get_focus_inactive(seat, |
147 | &root_container); | 147 | &root_container); |
148 | struct sway_container *cont = container_view_create(focus, view); | 148 | struct sway_container *cont = container_view_create(focus, view); |
149 | view->swayc = cont; | 149 | view->swayc = cont; |
150 | arrange_windows(cont->parent, -1, -1); | 150 | arrange_windows(cont->parent, -1, -1); |
151 | sway_input_manager_set_focus(input_manager, cont); | 151 | input_manager_set_focus(input_manager, cont); |
152 | } | 152 | } |
153 | 153 | ||
154 | view_damage_whole(sway_surface->view); | 154 | view_damage_whole(sway_surface->view); |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index d608a9cf..7d05e942 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -84,7 +84,7 @@ static struct sway_container *container_at_cursor(struct sway_cursor *cursor, | |||
84 | 84 | ||
85 | // find the focused workspace on the output for this seat | 85 | // find the focused workspace on the output for this seat |
86 | struct sway_container *ws = | 86 | struct sway_container *ws = |
87 | sway_seat_get_focus_inactive(cursor->seat, output->swayc); | 87 | seat_get_focus_inactive(cursor->seat, output->swayc); |
88 | if (ws && ws->type != C_WORKSPACE) { | 88 | if (ws && ws->type != C_WORKSPACE) { |
89 | ws = container_parent(ws, C_WORKSPACE); | 89 | ws = container_parent(ws, C_WORKSPACE); |
90 | } | 90 | } |
@@ -129,7 +129,7 @@ static void cursor_send_pointer_motion(struct sway_cursor *cursor, | |||
129 | double sx, sy; | 129 | double sx, sy; |
130 | struct sway_container *c = container_at_cursor(cursor, &surface, &sx, &sy); | 130 | struct sway_container *c = container_at_cursor(cursor, &surface, &sx, &sy); |
131 | if (c && config->focus_follows_mouse) { | 131 | if (c && config->focus_follows_mouse) { |
132 | sway_seat_set_focus_warp(cursor->seat, c, false); | 132 | seat_set_focus_warp(cursor->seat, c, false); |
133 | } | 133 | } |
134 | 134 | ||
135 | // reset cursor if switching between clients | 135 | // reset cursor if switching between clients |
@@ -191,15 +191,15 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { | |||
191 | if (new_ws && new_ws->type != C_WORKSPACE) { | 191 | if (new_ws && new_ws->type != C_WORKSPACE) { |
192 | new_ws = container_parent(new_ws, C_WORKSPACE); | 192 | new_ws = container_parent(new_ws, C_WORKSPACE); |
193 | } | 193 | } |
194 | struct sway_container *old_ws = sway_seat_get_focus(cursor->seat); | 194 | struct sway_container *old_ws = seat_get_focus(cursor->seat); |
195 | if (old_ws && old_ws->type != C_WORKSPACE) { | 195 | if (old_ws && old_ws->type != C_WORKSPACE) { |
196 | old_ws = container_parent(old_ws, C_WORKSPACE); | 196 | old_ws = container_parent(old_ws, C_WORKSPACE); |
197 | } | 197 | } |
198 | if (new_ws != old_ws) { | 198 | if (new_ws != old_ws) { |
199 | sway_seat_set_focus(cursor->seat, cont); | 199 | seat_set_focus(cursor->seat, cont); |
200 | } | 200 | } |
201 | } else { | 201 | } else { |
202 | sway_seat_set_focus(cursor->seat, cont); | 202 | seat_set_focus(cursor->seat, cont); |
203 | } | 203 | } |
204 | 204 | ||
205 | wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, event->time_msec, | 205 | wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, event->time_msec, |
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index d421a03f..c3507f65 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c | |||
@@ -26,7 +26,7 @@ struct seat_config *current_seat_config = NULL; | |||
26 | struct sway_seat *input_manager_current_seat(struct sway_input_manager *input) { | 26 | struct sway_seat *input_manager_current_seat(struct sway_input_manager *input) { |
27 | struct sway_seat *seat = config->handler_context.seat; | 27 | struct sway_seat *seat = config->handler_context.seat; |
28 | if (!seat) { | 28 | if (!seat) { |
29 | seat = sway_input_manager_get_default_seat(input_manager); | 29 | seat = input_manager_get_default_seat(input_manager); |
30 | } | 30 | } |
31 | return seat; | 31 | return seat; |
32 | } | 32 | } |
@@ -40,7 +40,7 @@ struct sway_seat *input_manager_get_seat( | |||
40 | } | 40 | } |
41 | } | 41 | } |
42 | 42 | ||
43 | return sway_seat_create(input, seat_name); | 43 | return seat_create(input, seat_name); |
44 | } | 44 | } |
45 | 45 | ||
46 | static char *get_device_identifier(struct wlr_input_device *device) { | 46 | static char *get_device_identifier(struct wlr_input_device *device) { |
@@ -83,7 +83,8 @@ static struct sway_input_device *input_sway_device_from_wlr( | |||
83 | static bool input_has_seat_configuration(struct sway_input_manager *input) { | 83 | static bool input_has_seat_configuration(struct sway_input_manager *input) { |
84 | struct sway_seat *seat = NULL; | 84 | struct sway_seat *seat = NULL; |
85 | wl_list_for_each(seat, &input->seats, link) { | 85 | wl_list_for_each(seat, &input->seats, link) { |
86 | if (seat->config) { | 86 | struct seat_config *seat_config = seat_get_config(seat); |
87 | if (seat_config) { | ||
87 | return true; | 88 | return true; |
88 | } | 89 | } |
89 | } | 90 | } |
@@ -91,9 +92,10 @@ static bool input_has_seat_configuration(struct sway_input_manager *input) { | |||
91 | return false; | 92 | return false; |
92 | } | 93 | } |
93 | 94 | ||
94 | static void sway_input_manager_libinput_config_pointer(struct sway_input_device *input_device) { | 95 | static void input_manager_libinput_config_pointer( |
96 | struct sway_input_device *input_device) { | ||
95 | struct wlr_input_device *wlr_device = input_device->wlr_device; | 97 | struct wlr_input_device *wlr_device = input_device->wlr_device; |
96 | struct input_config *ic = input_device->config; | 98 | struct input_config *ic = input_device_get_config(input_device); |
97 | struct libinput_device *libinput_device; | 99 | struct libinput_device *libinput_device; |
98 | 100 | ||
99 | if (!ic || !wlr_input_device_is_libinput(wlr_device)) { | 101 | if (!ic || !wlr_input_device_is_libinput(wlr_device)) { |
@@ -101,22 +103,27 @@ static void sway_input_manager_libinput_config_pointer(struct sway_input_device | |||
101 | } | 103 | } |
102 | 104 | ||
103 | libinput_device = wlr_libinput_get_device_handle(wlr_device); | 105 | libinput_device = wlr_libinput_get_device_handle(wlr_device); |
104 | wlr_log(L_DEBUG, "sway_input_manager_libinput_config_pointer(%s)", ic->identifier); | 106 | wlr_log(L_DEBUG, "input_manager_libinput_config_pointer(%s)", |
107 | ic->identifier); | ||
105 | 108 | ||
106 | if (ic->accel_profile != INT_MIN) { | 109 | if (ic->accel_profile != INT_MIN) { |
107 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) accel_set_profile(%d)", | 110 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) accel_set_profile(%d)", |
108 | ic->identifier, ic->accel_profile); | 111 | ic->identifier, ic->accel_profile); |
109 | libinput_device_config_accel_set_profile(libinput_device, ic->accel_profile); | 112 | libinput_device_config_accel_set_profile(libinput_device, |
113 | ic->accel_profile); | ||
110 | } | 114 | } |
111 | if (ic->click_method != INT_MIN) { | 115 | if (ic->click_method != INT_MIN) { |
112 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) click_set_method(%d)", | 116 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) click_set_method(%d)", |
113 | ic->identifier, ic->click_method); | 117 | ic->identifier, ic->click_method); |
114 | libinput_device_config_click_set_method(libinput_device, ic->click_method); | 118 | libinput_device_config_click_set_method(libinput_device, |
119 | ic->click_method); | ||
115 | } | 120 | } |
116 | if (ic->drag_lock != INT_MIN) { | 121 | if (ic->drag_lock != INT_MIN) { |
117 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) tap_set_drag_lock_enabled(%d)", | 122 | wlr_log(L_DEBUG, |
123 | "libinput_config_pointer(%s) tap_set_drag_lock_enabled(%d)", | ||
118 | ic->identifier, ic->click_method); | 124 | ic->identifier, ic->click_method); |
119 | libinput_device_config_tap_set_drag_lock_enabled(libinput_device, ic->drag_lock); | 125 | libinput_device_config_tap_set_drag_lock_enabled(libinput_device, |
126 | ic->drag_lock); | ||
120 | } | 127 | } |
121 | if (ic->dwt != INT_MIN) { | 128 | if (ic->dwt != INT_MIN) { |
122 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) dwt_set_enabled(%d)", | 129 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) dwt_set_enabled(%d)", |
@@ -124,34 +131,43 @@ static void sway_input_manager_libinput_config_pointer(struct sway_input_device | |||
124 | libinput_device_config_dwt_set_enabled(libinput_device, ic->dwt); | 131 | libinput_device_config_dwt_set_enabled(libinput_device, ic->dwt); |
125 | } | 132 | } |
126 | if (ic->left_handed != INT_MIN) { | 133 | if (ic->left_handed != INT_MIN) { |
127 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) left_handed_set_enabled(%d)", | 134 | wlr_log(L_DEBUG, |
135 | "libinput_config_pointer(%s) left_handed_set_enabled(%d)", | ||
128 | ic->identifier, ic->left_handed); | 136 | ic->identifier, ic->left_handed); |
129 | libinput_device_config_left_handed_set(libinput_device, ic->left_handed); | 137 | libinput_device_config_left_handed_set(libinput_device, |
138 | ic->left_handed); | ||
130 | } | 139 | } |
131 | if (ic->middle_emulation != INT_MIN) { | 140 | if (ic->middle_emulation != INT_MIN) { |
132 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) middle_emulation_set_enabled(%d)", | 141 | wlr_log(L_DEBUG, |
142 | "libinput_config_pointer(%s) middle_emulation_set_enabled(%d)", | ||
133 | ic->identifier, ic->middle_emulation); | 143 | ic->identifier, ic->middle_emulation); |
134 | libinput_device_config_middle_emulation_set_enabled(libinput_device, ic->middle_emulation); | 144 | libinput_device_config_middle_emulation_set_enabled(libinput_device, |
145 | ic->middle_emulation); | ||
135 | } | 146 | } |
136 | if (ic->natural_scroll != INT_MIN) { | 147 | if (ic->natural_scroll != INT_MIN) { |
137 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) natural_scroll_set_enabled(%d)", | 148 | wlr_log(L_DEBUG, |
149 | "libinput_config_pointer(%s) natural_scroll_set_enabled(%d)", | ||
138 | ic->identifier, ic->natural_scroll); | 150 | ic->identifier, ic->natural_scroll); |
139 | libinput_device_config_scroll_set_natural_scroll_enabled(libinput_device, ic->natural_scroll); | 151 | libinput_device_config_scroll_set_natural_scroll_enabled( |
152 | libinput_device, ic->natural_scroll); | ||
140 | } | 153 | } |
141 | if (ic->pointer_accel != FLT_MIN) { | 154 | if (ic->pointer_accel != FLT_MIN) { |
142 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) accel_set_speed(%f)", | 155 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) accel_set_speed(%f)", |
143 | ic->identifier, ic->pointer_accel); | 156 | ic->identifier, ic->pointer_accel); |
144 | libinput_device_config_accel_set_speed(libinput_device, ic->pointer_accel); | 157 | libinput_device_config_accel_set_speed(libinput_device, |
158 | ic->pointer_accel); | ||
145 | } | 159 | } |
146 | if (ic->scroll_method != INT_MIN) { | 160 | if (ic->scroll_method != INT_MIN) { |
147 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) scroll_set_method(%d)", | 161 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) scroll_set_method(%d)", |
148 | ic->identifier, ic->scroll_method); | 162 | ic->identifier, ic->scroll_method); |
149 | libinput_device_config_scroll_set_method(libinput_device, ic->scroll_method); | 163 | libinput_device_config_scroll_set_method(libinput_device, |
164 | ic->scroll_method); | ||
150 | } | 165 | } |
151 | if (ic->send_events != INT_MIN) { | 166 | if (ic->send_events != INT_MIN) { |
152 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) send_events_set_mode(%d)", | 167 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) send_events_set_mode(%d)", |
153 | ic->identifier, ic->send_events); | 168 | ic->identifier, ic->send_events); |
154 | libinput_device_config_send_events_set_mode(libinput_device, ic->send_events); | 169 | libinput_device_config_send_events_set_mode(libinput_device, |
170 | ic->send_events); | ||
155 | } | 171 | } |
156 | if (ic->tap != INT_MIN) { | 172 | if (ic->tap != INT_MIN) { |
157 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) tap_set_enabled(%d)", | 173 | wlr_log(L_DEBUG, "libinput_config_pointer(%s) tap_set_enabled(%d)", |
@@ -175,12 +191,11 @@ static void handle_device_destroy(struct wl_listener *listener, void *data) { | |||
175 | 191 | ||
176 | struct sway_seat *seat = NULL; | 192 | struct sway_seat *seat = NULL; |
177 | wl_list_for_each(seat, &input_manager->seats, link) { | 193 | wl_list_for_each(seat, &input_manager->seats, link) { |
178 | sway_seat_remove_device(seat, input_device); | 194 | seat_remove_device(seat, input_device); |
179 | } | 195 | } |
180 | 196 | ||
181 | wl_list_remove(&input_device->link); | 197 | wl_list_remove(&input_device->link); |
182 | wl_list_remove(&input_device->device_destroy.link); | 198 | wl_list_remove(&input_device->device_destroy.link); |
183 | free_input_config(input_device->config); | ||
184 | free(input_device->identifier); | 199 | free(input_device->identifier); |
185 | free(input_device); | 200 | free(input_device); |
186 | } | 201 | } |
@@ -203,44 +218,36 @@ static void handle_new_input(struct wl_listener *listener, void *data) { | |||
203 | wlr_log(L_DEBUG, "adding device: '%s'", | 218 | wlr_log(L_DEBUG, "adding device: '%s'", |
204 | input_device->identifier); | 219 | input_device->identifier); |
205 | 220 | ||
206 | // find config | ||
207 | for (int i = 0; i < config->input_configs->length; ++i) { | ||
208 | struct input_config *input_config = config->input_configs->items[i]; | ||
209 | if (strcmp(input_config->identifier, input_device->identifier) == 0) { | ||
210 | free_input_config(input_device->config); | ||
211 | input_device->config = copy_input_config(input_config); | ||
212 | break; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) { | 221 | if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) { |
217 | sway_input_manager_libinput_config_pointer(input_device); | 222 | input_manager_libinput_config_pointer(input_device); |
218 | } | 223 | } |
219 | 224 | ||
220 | struct sway_seat *seat = NULL; | 225 | struct sway_seat *seat = NULL; |
221 | if (!input_has_seat_configuration(input)) { | 226 | if (!input_has_seat_configuration(input)) { |
222 | wlr_log(L_DEBUG, "no seat configuration, using default seat"); | 227 | wlr_log(L_DEBUG, "no seat configuration, using default seat"); |
223 | seat = input_manager_get_seat(input, default_seat); | 228 | seat = input_manager_get_seat(input, default_seat); |
224 | sway_seat_add_device(seat, input_device); | 229 | seat_add_device(seat, input_device); |
225 | return; | 230 | return; |
226 | } | 231 | } |
227 | 232 | ||
228 | bool added = false; | 233 | bool added = false; |
229 | wl_list_for_each(seat, &input->seats, link) { | 234 | wl_list_for_each(seat, &input->seats, link) { |
230 | bool has_attachment = seat->config && | 235 | struct seat_config *seat_config = seat_get_config(seat); |
231 | (seat_config_get_attachment(seat->config, input_device->identifier) || | 236 | bool has_attachment = seat_config && |
232 | seat_config_get_attachment(seat->config, "*")); | 237 | (seat_config_get_attachment(seat_config, input_device->identifier) || |
238 | seat_config_get_attachment(seat_config, "*")); | ||
233 | 239 | ||
234 | if (has_attachment) { | 240 | if (has_attachment) { |
235 | sway_seat_add_device(seat, input_device); | 241 | seat_add_device(seat, input_device); |
236 | added = true; | 242 | added = true; |
237 | } | 243 | } |
238 | } | 244 | } |
239 | 245 | ||
240 | if (!added) { | 246 | if (!added) { |
241 | wl_list_for_each(seat, &input->seats, link) { | 247 | wl_list_for_each(seat, &input->seats, link) { |
242 | if (seat->config && seat->config->fallback == 1) { | 248 | struct seat_config *seat_config = seat_get_config(seat); |
243 | sway_seat_add_device(seat, input_device); | 249 | if (seat_config && seat_config->fallback == 1) { |
250 | seat_add_device(seat, input_device); | ||
244 | added = true; | 251 | added = true; |
245 | } | 252 | } |
246 | } | 253 | } |
@@ -256,7 +263,7 @@ static void handle_new_input(struct wl_listener *listener, void *data) { | |||
256 | input_device->device_destroy.notify = handle_device_destroy; | 263 | input_device->device_destroy.notify = handle_device_destroy; |
257 | } | 264 | } |
258 | 265 | ||
259 | struct sway_input_manager *sway_input_manager_create( | 266 | struct sway_input_manager *input_manager_create( |
260 | struct sway_server *server) { | 267 | struct sway_server *server) { |
261 | struct sway_input_manager *input = | 268 | struct sway_input_manager *input = |
262 | calloc(1, sizeof(struct sway_input_manager)); | 269 | calloc(1, sizeof(struct sway_input_manager)); |
@@ -277,11 +284,11 @@ struct sway_input_manager *sway_input_manager_create( | |||
277 | return input; | 284 | return input; |
278 | } | 285 | } |
279 | 286 | ||
280 | bool sway_input_manager_has_focus(struct sway_input_manager *input, | 287 | bool input_manager_has_focus(struct sway_input_manager *input, |
281 | struct sway_container *container) { | 288 | struct sway_container *container) { |
282 | struct sway_seat *seat = NULL; | 289 | struct sway_seat *seat = NULL; |
283 | wl_list_for_each(seat, &input->seats, link) { | 290 | wl_list_for_each(seat, &input->seats, link) { |
284 | if (sway_seat_get_focus(seat) == container) { | 291 | if (seat_get_focus(seat) == container) { |
285 | return true; | 292 | return true; |
286 | } | 293 | } |
287 | } | 294 | } |
@@ -289,35 +296,32 @@ bool sway_input_manager_has_focus(struct sway_input_manager *input, | |||
289 | return false; | 296 | return false; |
290 | } | 297 | } |
291 | 298 | ||
292 | void sway_input_manager_set_focus(struct sway_input_manager *input, | 299 | void input_manager_set_focus(struct sway_input_manager *input, |
293 | struct sway_container *container) { | 300 | struct sway_container *container) { |
294 | struct sway_seat *seat ; | 301 | struct sway_seat *seat ; |
295 | wl_list_for_each(seat, &input->seats, link) { | 302 | wl_list_for_each(seat, &input->seats, link) { |
296 | sway_seat_set_focus(seat, container); | 303 | seat_set_focus(seat, container); |
297 | } | 304 | } |
298 | } | 305 | } |
299 | 306 | ||
300 | void sway_input_manager_apply_input_config(struct sway_input_manager *input, | 307 | void input_manager_apply_input_config(struct sway_input_manager *input, |
301 | struct input_config *input_config) { | 308 | struct input_config *input_config) { |
302 | struct sway_input_device *input_device = NULL; | 309 | struct sway_input_device *input_device = NULL; |
303 | wl_list_for_each(input_device, &input->devices, link) { | 310 | wl_list_for_each(input_device, &input->devices, link) { |
304 | if (strcmp(input_device->identifier, input_config->identifier) == 0) { | 311 | if (strcmp(input_device->identifier, input_config->identifier) == 0) { |
305 | free_input_config(input_device->config); | ||
306 | input_device->config = copy_input_config(input_config); | ||
307 | |||
308 | if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) { | 312 | if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) { |
309 | sway_input_manager_libinput_config_pointer(input_device); | 313 | input_manager_libinput_config_pointer(input_device); |
310 | } | 314 | } |
311 | 315 | ||
312 | struct sway_seat *seat = NULL; | 316 | struct sway_seat *seat = NULL; |
313 | wl_list_for_each(seat, &input->seats, link) { | 317 | wl_list_for_each(seat, &input->seats, link) { |
314 | sway_seat_configure_device(seat, input_device); | 318 | seat_configure_device(seat, input_device); |
315 | } | 319 | } |
316 | } | 320 | } |
317 | } | 321 | } |
318 | } | 322 | } |
319 | 323 | ||
320 | void sway_input_manager_apply_seat_config(struct sway_input_manager *input, | 324 | void input_manager_apply_seat_config(struct sway_input_manager *input, |
321 | struct seat_config *seat_config) { | 325 | struct seat_config *seat_config) { |
322 | wlr_log(L_DEBUG, "applying new seat config for seat %s", | 326 | wlr_log(L_DEBUG, "applying new seat config for seat %s", |
323 | seat_config->name); | 327 | seat_config->name); |
@@ -326,7 +330,7 @@ void sway_input_manager_apply_seat_config(struct sway_input_manager *input, | |||
326 | return; | 330 | return; |
327 | } | 331 | } |
328 | 332 | ||
329 | sway_seat_set_config(seat, seat_config); | 333 | seat_apply_config(seat, seat_config); |
330 | 334 | ||
331 | // for every device, try to add it to a seat and if no seat has it | 335 | // for every device, try to add it to a seat and if no seat has it |
332 | // attached, add it to the fallback seats. | 336 | // attached, add it to the fallback seats. |
@@ -335,11 +339,12 @@ void sway_input_manager_apply_seat_config(struct sway_input_manager *input, | |||
335 | list_t *seat_list = create_list(); | 339 | list_t *seat_list = create_list(); |
336 | struct sway_seat *seat = NULL; | 340 | struct sway_seat *seat = NULL; |
337 | wl_list_for_each(seat, &input->seats, link) { | 341 | wl_list_for_each(seat, &input->seats, link) { |
338 | if (!seat->config) { | 342 | struct seat_config *seat_config = seat_get_config(seat); |
343 | if (!seat_config) { | ||
339 | continue; | 344 | continue; |
340 | } | 345 | } |
341 | if (seat_config_get_attachment(seat->config, "*") || | 346 | if (seat_config_get_attachment(seat_config, "*") || |
342 | seat_config_get_attachment(seat->config, | 347 | seat_config_get_attachment(seat_config, |
343 | input_device->identifier)) { | 348 | input_device->identifier)) { |
344 | list_add(seat_list, seat); | 349 | list_add(seat_list, seat); |
345 | } | 350 | } |
@@ -355,17 +360,18 @@ void sway_input_manager_apply_seat_config(struct sway_input_manager *input, | |||
355 | } | 360 | } |
356 | } | 361 | } |
357 | if (attached) { | 362 | if (attached) { |
358 | sway_seat_add_device(seat, input_device); | 363 | seat_add_device(seat, input_device); |
359 | } else { | 364 | } else { |
360 | sway_seat_remove_device(seat, input_device); | 365 | seat_remove_device(seat, input_device); |
361 | } | 366 | } |
362 | } | 367 | } |
363 | } else { | 368 | } else { |
364 | wl_list_for_each(seat, &input->seats, link) { | 369 | wl_list_for_each(seat, &input->seats, link) { |
365 | if (seat->config && seat->config->fallback == 1) { | 370 | struct seat_config *seat_config = seat_get_config(seat); |
366 | sway_seat_add_device(seat, input_device); | 371 | if (seat_config && seat_config->fallback == 1) { |
372 | seat_add_device(seat, input_device); | ||
367 | } else { | 373 | } else { |
368 | sway_seat_remove_device(seat, input_device); | 374 | seat_remove_device(seat, input_device); |
369 | } | 375 | } |
370 | } | 376 | } |
371 | } | 377 | } |
@@ -373,14 +379,14 @@ void sway_input_manager_apply_seat_config(struct sway_input_manager *input, | |||
373 | } | 379 | } |
374 | } | 380 | } |
375 | 381 | ||
376 | void sway_input_manager_configure_xcursor(struct sway_input_manager *input) { | 382 | void input_manager_configure_xcursor(struct sway_input_manager *input) { |
377 | struct sway_seat *seat = NULL; | 383 | struct sway_seat *seat = NULL; |
378 | wl_list_for_each(seat, &input->seats, link) { | 384 | wl_list_for_each(seat, &input->seats, link) { |
379 | sway_seat_configure_xcursor(seat); | 385 | seat_configure_xcursor(seat); |
380 | } | 386 | } |
381 | } | 387 | } |
382 | 388 | ||
383 | struct sway_seat *sway_input_manager_get_default_seat( | 389 | struct sway_seat *input_manager_get_default_seat( |
384 | struct sway_input_manager *input) { | 390 | struct sway_input_manager *input) { |
385 | struct sway_seat *seat = NULL; | 391 | struct sway_seat *seat = NULL; |
386 | wl_list_for_each(seat, &input->seats, link) { | 392 | wl_list_for_each(seat, &input->seats, link) { |
@@ -390,3 +396,15 @@ struct sway_seat *sway_input_manager_get_default_seat( | |||
390 | } | 396 | } |
391 | return seat; | 397 | return seat; |
392 | } | 398 | } |
399 | |||
400 | struct input_config *input_device_get_config(struct sway_input_device *device) { | ||
401 | struct input_config *input_config = NULL; | ||
402 | for (int i = 0; i < config->input_configs->length; ++i) { | ||
403 | input_config = config->input_configs->items[i]; | ||
404 | if (strcmp(input_config->identifier, device->identifier) == 0) { | ||
405 | return input_config; | ||
406 | } | ||
407 | } | ||
408 | |||
409 | return NULL; | ||
410 | } | ||
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 8d22b684..dbb0c359 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c | |||
@@ -428,7 +428,7 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) { | |||
428 | struct xkb_rule_names rules; | 428 | struct xkb_rule_names rules; |
429 | memset(&rules, 0, sizeof(rules)); | 429 | memset(&rules, 0, sizeof(rules)); |
430 | struct input_config *input_config = | 430 | struct input_config *input_config = |
431 | keyboard->seat_device->input_device->config; | 431 | input_device_get_config(keyboard->seat_device->input_device); |
432 | struct wlr_input_device *wlr_device = | 432 | struct wlr_input_device *wlr_device = |
433 | keyboard->seat_device->input_device->wlr_device; | 433 | keyboard->seat_device->input_device->wlr_device; |
434 | 434 | ||
diff --git a/sway/input/seat.c b/sway/input/seat.c index 1fd204d4..c41f7b2e 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -26,8 +26,7 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) { | |||
26 | free(seat_device); | 26 | free(seat_device); |
27 | } | 27 | } |
28 | 28 | ||
29 | void sway_seat_destroy(struct sway_seat *seat) { | 29 | void seat_destroy(struct sway_seat *seat) { |
30 | // TODO destroy seat containers | ||
31 | struct sway_seat_device *seat_device, *next; | 30 | struct sway_seat_device *seat_device, *next; |
32 | wl_list_for_each_safe(seat_device, next, &seat->devices, link) { | 31 | wl_list_for_each_safe(seat_device, next, &seat->devices, link) { |
33 | seat_device_destroy(seat_device); | 32 | seat_device_destroy(seat_device); |
@@ -90,7 +89,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener, | |||
90 | struct sway_seat *seat = seat_con->seat; | 89 | struct sway_seat *seat = seat_con->seat; |
91 | struct sway_container *con = seat_con->container; | 90 | struct sway_container *con = seat_con->container; |
92 | struct sway_container *parent = con->parent; | 91 | struct sway_container *parent = con->parent; |
93 | struct sway_container *focus = sway_seat_get_focus(seat); | 92 | struct sway_container *focus = seat_get_focus(seat); |
94 | 93 | ||
95 | bool set_focus = | 94 | bool set_focus = |
96 | focus != NULL && | 95 | focus != NULL && |
@@ -102,7 +101,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener, | |||
102 | if (set_focus) { | 101 | if (set_focus) { |
103 | struct sway_container *next_focus = NULL; | 102 | struct sway_container *next_focus = NULL; |
104 | while (next_focus == NULL) { | 103 | while (next_focus == NULL) { |
105 | next_focus = sway_seat_get_focus_by_type(seat, parent, C_VIEW); | 104 | next_focus = seat_get_focus_by_type(seat, parent, C_VIEW); |
106 | 105 | ||
107 | if (next_focus == NULL && parent->type == C_WORKSPACE) { | 106 | if (next_focus == NULL && parent->type == C_WORKSPACE) { |
108 | next_focus = parent; | 107 | next_focus = parent; |
@@ -114,10 +113,10 @@ static void handle_seat_container_destroy(struct wl_listener *listener, | |||
114 | 113 | ||
115 | // the structure change might have caused it to move up to the top of | 114 | // the structure change might have caused it to move up to the top of |
116 | // the focus stack without sending focus notifications to the view | 115 | // the focus stack without sending focus notifications to the view |
117 | if (sway_seat_get_focus(seat) == next_focus) { | 116 | if (seat_get_focus(seat) == next_focus) { |
118 | seat_send_focus(seat, next_focus); | 117 | seat_send_focus(seat, next_focus); |
119 | } else { | 118 | } else { |
120 | sway_seat_set_focus(seat, next_focus); | 119 | seat_set_focus(seat, next_focus); |
121 | } | 120 | } |
122 | } | 121 | } |
123 | } | 122 | } |
@@ -171,7 +170,7 @@ static void collect_focus_iter(struct sway_container *con, void *data) { | |||
171 | wl_list_insert(&seat->focus_stack, &seat_con->link); | 170 | wl_list_insert(&seat->focus_stack, &seat_con->link); |
172 | } | 171 | } |
173 | 172 | ||
174 | struct sway_seat *sway_seat_create(struct sway_input_manager *input, | 173 | struct sway_seat *seat_create(struct sway_input_manager *input, |
175 | const char *seat_name) { | 174 | const char *seat_name) { |
176 | struct sway_seat *seat = calloc(1, sizeof(struct sway_seat)); | 175 | struct sway_seat *seat = calloc(1, sizeof(struct sway_seat)); |
177 | if (!seat) { | 176 | if (!seat) { |
@@ -194,7 +193,8 @@ struct sway_seat *sway_seat_create(struct sway_input_manager *input, | |||
194 | // init the focus stack | 193 | // init the focus stack |
195 | wl_list_init(&seat->focus_stack); | 194 | wl_list_init(&seat->focus_stack); |
196 | 195 | ||
197 | container_for_each_descendant_dfs(&root_container, collect_focus_iter, seat); | 196 | container_for_each_descendant_dfs(&root_container, |
197 | collect_focus_iter, seat); | ||
198 | 198 | ||
199 | wl_signal_add(&root_container.sway_root->events.new_container, | 199 | wl_signal_add(&root_container.sway_root->events.new_container, |
200 | &seat->new_container); | 200 | &seat->new_container); |
@@ -208,7 +208,7 @@ struct sway_seat *sway_seat_create(struct sway_input_manager *input, | |||
208 | WL_SEAT_CAPABILITY_POINTER | | 208 | WL_SEAT_CAPABILITY_POINTER | |
209 | WL_SEAT_CAPABILITY_TOUCH); | 209 | WL_SEAT_CAPABILITY_TOUCH); |
210 | 210 | ||
211 | sway_seat_configure_xcursor(seat); | 211 | seat_configure_xcursor(seat); |
212 | 212 | ||
213 | wl_list_insert(&input->seats, &seat->link); | 213 | wl_list_insert(&input->seats, &seat->link); |
214 | 214 | ||
@@ -226,11 +226,12 @@ static void seat_configure_keyboard(struct sway_seat *seat, | |||
226 | if (!seat_device->keyboard) { | 226 | if (!seat_device->keyboard) { |
227 | sway_keyboard_create(seat, seat_device); | 227 | sway_keyboard_create(seat, seat_device); |
228 | } | 228 | } |
229 | struct wlr_keyboard *wlr_keyboard = seat_device->input_device->wlr_device->keyboard; | 229 | struct wlr_keyboard *wlr_keyboard = |
230 | seat_device->input_device->wlr_device->keyboard; | ||
230 | sway_keyboard_configure(seat_device->keyboard); | 231 | sway_keyboard_configure(seat_device->keyboard); |
231 | wlr_seat_set_keyboard(seat->wlr_seat, | 232 | wlr_seat_set_keyboard(seat->wlr_seat, |
232 | seat_device->input_device->wlr_device); | 233 | seat_device->input_device->wlr_device); |
233 | struct sway_container *focus = sway_seat_get_focus(seat); | 234 | struct sway_container *focus = seat_get_focus(seat); |
234 | if (focus && focus->type == C_VIEW) { | 235 | if (focus && focus->type == C_VIEW) { |
235 | // force notify reenter to pick up the new configuration | 236 | // force notify reenter to pick up the new configuration |
236 | wlr_seat_keyboard_clear_focus(seat->wlr_seat); | 237 | wlr_seat_keyboard_clear_focus(seat->wlr_seat); |
@@ -240,7 +241,7 @@ static void seat_configure_keyboard(struct sway_seat *seat, | |||
240 | } | 241 | } |
241 | } | 242 | } |
242 | 243 | ||
243 | static struct sway_seat_device *sway_seat_get_device(struct sway_seat *seat, | 244 | static struct sway_seat_device *seat_get_device(struct sway_seat *seat, |
244 | struct sway_input_device *input_device) { | 245 | struct sway_input_device *input_device) { |
245 | struct sway_seat_device *seat_device = NULL; | 246 | struct sway_seat_device *seat_device = NULL; |
246 | wl_list_for_each(seat_device, &seat->devices, link) { | 247 | wl_list_for_each(seat_device, &seat->devices, link) { |
@@ -252,19 +253,14 @@ static struct sway_seat_device *sway_seat_get_device(struct sway_seat *seat, | |||
252 | return NULL; | 253 | return NULL; |
253 | } | 254 | } |
254 | 255 | ||
255 | void sway_seat_configure_device(struct sway_seat *seat, | 256 | void seat_configure_device(struct sway_seat *seat, |
256 | struct sway_input_device *input_device) { | 257 | struct sway_input_device *input_device) { |
257 | struct sway_seat_device *seat_device = | 258 | struct sway_seat_device *seat_device = |
258 | sway_seat_get_device(seat, input_device); | 259 | seat_get_device(seat, input_device); |
259 | if (!seat_device) { | 260 | if (!seat_device) { |
260 | return; | 261 | return; |
261 | } | 262 | } |
262 | 263 | ||
263 | if (seat->config) { | ||
264 | seat_device->attachment_config = | ||
265 | seat_config_get_attachment(seat->config, input_device->identifier); | ||
266 | } | ||
267 | |||
268 | switch (input_device->wlr_device->type) { | 264 | switch (input_device->wlr_device->type) { |
269 | case WLR_INPUT_DEVICE_POINTER: | 265 | case WLR_INPUT_DEVICE_POINTER: |
270 | seat_configure_pointer(seat, seat_device); | 266 | seat_configure_pointer(seat, seat_device); |
@@ -280,10 +276,10 @@ void sway_seat_configure_device(struct sway_seat *seat, | |||
280 | } | 276 | } |
281 | } | 277 | } |
282 | 278 | ||
283 | void sway_seat_add_device(struct sway_seat *seat, | 279 | void seat_add_device(struct sway_seat *seat, |
284 | struct sway_input_device *input_device) { | 280 | struct sway_input_device *input_device) { |
285 | if (sway_seat_get_device(seat, input_device)) { | 281 | if (seat_get_device(seat, input_device)) { |
286 | sway_seat_configure_device(seat, input_device); | 282 | seat_configure_device(seat, input_device); |
287 | return; | 283 | return; |
288 | } | 284 | } |
289 | 285 | ||
@@ -301,13 +297,13 @@ void sway_seat_add_device(struct sway_seat *seat, | |||
301 | seat_device->input_device = input_device; | 297 | seat_device->input_device = input_device; |
302 | wl_list_insert(&seat->devices, &seat_device->link); | 298 | wl_list_insert(&seat->devices, &seat_device->link); |
303 | 299 | ||
304 | sway_seat_configure_device(seat, input_device); | 300 | seat_configure_device(seat, input_device); |
305 | } | 301 | } |
306 | 302 | ||
307 | void sway_seat_remove_device(struct sway_seat *seat, | 303 | void seat_remove_device(struct sway_seat *seat, |
308 | struct sway_input_device *input_device) { | 304 | struct sway_input_device *input_device) { |
309 | struct sway_seat_device *seat_device = | 305 | struct sway_seat_device *seat_device = |
310 | sway_seat_get_device(seat, input_device); | 306 | seat_get_device(seat, input_device); |
311 | 307 | ||
312 | if (!seat_device) { | 308 | if (!seat_device) { |
313 | return; | 309 | return; |
@@ -319,7 +315,7 @@ void sway_seat_remove_device(struct sway_seat *seat, | |||
319 | seat_device_destroy(seat_device); | 315 | seat_device_destroy(seat_device); |
320 | } | 316 | } |
321 | 317 | ||
322 | void sway_seat_configure_xcursor(struct sway_seat *seat) { | 318 | void seat_configure_xcursor(struct sway_seat *seat) { |
323 | // TODO configure theme and size | 319 | // TODO configure theme and size |
324 | const char *cursor_theme = NULL; | 320 | const char *cursor_theme = NULL; |
325 | 321 | ||
@@ -334,7 +330,8 @@ void sway_seat_configure_xcursor(struct sway_seat *seat) { | |||
334 | } | 330 | } |
335 | 331 | ||
336 | for (int i = 0; i < root_container.children->length; ++i) { | 332 | for (int i = 0; i < root_container.children->length; ++i) { |
337 | struct sway_container *output_container = root_container.children->items[i]; | 333 | struct sway_container *output_container = |
334 | root_container.children->items[i]; | ||
338 | struct wlr_output *output = | 335 | struct wlr_output *output = |
339 | output_container->sway_output->wlr_output; | 336 | output_container->sway_output->wlr_output; |
340 | bool result = | 337 | bool result = |
@@ -353,9 +350,9 @@ void sway_seat_configure_xcursor(struct sway_seat *seat) { | |||
353 | seat->cursor->cursor->y); | 350 | seat->cursor->cursor->y); |
354 | } | 351 | } |
355 | 352 | ||
356 | void sway_seat_set_focus_warp(struct sway_seat *seat, | 353 | void seat_set_focus_warp(struct sway_seat *seat, |
357 | struct sway_container *container, bool warp) { | 354 | struct sway_container *container, bool warp) { |
358 | struct sway_container *last_focus = sway_seat_get_focus(seat); | 355 | struct sway_container *last_focus = seat_get_focus(seat); |
359 | 356 | ||
360 | if (container && last_focus == container) { | 357 | if (container && last_focus == container) { |
361 | return; | 358 | return; |
@@ -409,7 +406,7 @@ void sway_seat_set_focus_warp(struct sway_seat *seat, | |||
409 | } | 406 | } |
410 | 407 | ||
411 | if (last_focus && last_focus->type == C_VIEW && | 408 | if (last_focus && last_focus->type == C_VIEW && |
412 | !sway_input_manager_has_focus(seat->input, last_focus)) { | 409 | !input_manager_has_focus(seat->input, last_focus)) { |
413 | struct sway_view *view = last_focus->sway_view; | 410 | struct sway_view *view = last_focus->sway_view; |
414 | view_set_activated(view, false); | 411 | view_set_activated(view, false); |
415 | } | 412 | } |
@@ -417,24 +414,24 @@ void sway_seat_set_focus_warp(struct sway_seat *seat, | |||
417 | seat->has_focus = (container != NULL); | 414 | seat->has_focus = (container != NULL); |
418 | } | 415 | } |
419 | 416 | ||
420 | void sway_seat_set_focus(struct sway_seat *seat, | 417 | void seat_set_focus(struct sway_seat *seat, |
421 | struct sway_container *container) { | 418 | struct sway_container *container) { |
422 | sway_seat_set_focus_warp(seat, container, true); | 419 | seat_set_focus_warp(seat, container, true); |
423 | } | 420 | } |
424 | 421 | ||
425 | struct sway_container *sway_seat_get_focus_inactive(struct sway_seat *seat, | 422 | struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, |
426 | struct sway_container *container) { | 423 | struct sway_container *container) { |
427 | return sway_seat_get_focus_by_type(seat, container, C_TYPES); | 424 | return seat_get_focus_by_type(seat, container, C_TYPES); |
428 | } | 425 | } |
429 | 426 | ||
430 | struct sway_container *sway_seat_get_focus(struct sway_seat *seat) { | 427 | struct sway_container *sway_seat_get_focus(struct sway_seat *seat) { |
431 | if (!seat->has_focus) { | 428 | if (!seat->has_focus) { |
432 | return NULL; | 429 | return NULL; |
433 | } | 430 | } |
434 | return sway_seat_get_focus_inactive(seat, &root_container); | 431 | return seat_get_focus_inactive(seat, &root_container); |
435 | } | 432 | } |
436 | 433 | ||
437 | struct sway_container *sway_seat_get_focus_by_type(struct sway_seat *seat, | 434 | struct sway_container *seat_get_focus_by_type(struct sway_seat *seat, |
438 | struct sway_container *container, enum sway_container_type type) { | 435 | struct sway_container *container, enum sway_container_type type) { |
439 | struct sway_seat_container *current = NULL; | 436 | struct sway_seat_container *current = NULL; |
440 | struct sway_container *parent = NULL; | 437 | struct sway_container *parent = NULL; |
@@ -458,25 +455,34 @@ struct sway_container *sway_seat_get_focus_by_type(struct sway_seat *seat, | |||
458 | return NULL; | 455 | return NULL; |
459 | } | 456 | } |
460 | 457 | ||
461 | void sway_seat_set_config(struct sway_seat *seat, | 458 | struct sway_container *seat_get_focus(struct sway_seat *seat) { |
462 | struct seat_config *seat_config) { | 459 | if (!seat->has_focus) { |
463 | // clear configs | 460 | return NULL; |
464 | free_seat_config(seat->config); | 461 | } |
465 | seat->config = NULL; | 462 | return seat_get_focus_inactive(seat, &root_container); |
463 | } | ||
466 | 464 | ||
465 | void seat_apply_config(struct sway_seat *seat, | ||
466 | struct seat_config *seat_config) { | ||
467 | struct sway_seat_device *seat_device = NULL; | 467 | struct sway_seat_device *seat_device = NULL; |
468 | wl_list_for_each(seat_device, &seat->devices, link) { | ||
469 | seat_device->attachment_config = NULL; | ||
470 | } | ||
471 | 468 | ||
472 | if (!seat_config) { | 469 | if (!seat_config) { |
473 | return; | 470 | return; |
474 | } | 471 | } |
475 | 472 | ||
476 | // add configs | ||
477 | seat->config = copy_seat_config(seat_config); | ||
478 | |||
479 | wl_list_for_each(seat_device, &seat->devices, link) { | 473 | wl_list_for_each(seat_device, &seat->devices, link) { |
480 | sway_seat_configure_device(seat, seat_device->input_device); | 474 | seat_configure_device(seat, seat_device->input_device); |
475 | } | ||
476 | } | ||
477 | |||
478 | struct seat_config *seat_get_config(struct sway_seat *seat) { | ||
479 | struct seat_config *seat_config = NULL; | ||
480 | for (int i = 0; i < config->seat_configs->length; ++i ) { | ||
481 | seat_config = config->seat_configs->items[i]; | ||
482 | if (strcmp(seat->wlr_seat->name, seat_config->name) == 0) { | ||
483 | return seat_config; | ||
484 | } | ||
481 | } | 485 | } |
486 | |||
487 | return NULL; | ||
482 | } | 488 | } |
diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 7c5f7304..3427c8ec 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c | |||
@@ -88,11 +88,11 @@ static void ipc_json_describe_output(struct sway_container *container, json_obje | |||
88 | json_object_new_string( | 88 | json_object_new_string( |
89 | ipc_json_get_output_transform(wlr_output->transform))); | 89 | ipc_json_get_output_transform(wlr_output->transform))); |
90 | 90 | ||
91 | struct sway_seat *seat = sway_input_manager_get_default_seat(input_manager); | 91 | struct sway_seat *seat = input_manager_get_default_seat(input_manager); |
92 | const char *ws = NULL; | 92 | const char *ws = NULL; |
93 | if (seat) { | 93 | if (seat) { |
94 | struct sway_container *focus = | 94 | struct sway_container *focus = |
95 | sway_seat_get_focus_inactive(seat, container); | 95 | seat_get_focus_inactive(seat, container); |
96 | if (focus && focus->type != C_WORKSPACE) { | 96 | if (focus && focus->type != C_WORKSPACE) { |
97 | focus = container_parent(focus, C_WORKSPACE); | 97 | focus = container_parent(focus, C_WORKSPACE); |
98 | } | 98 | } |
@@ -139,8 +139,8 @@ json_object *ipc_json_describe_container(struct sway_container *c) { | |||
139 | return NULL; | 139 | return NULL; |
140 | } | 140 | } |
141 | 141 | ||
142 | struct sway_seat *seat = sway_input_manager_get_default_seat(input_manager); | 142 | struct sway_seat *seat = input_manager_get_default_seat(input_manager); |
143 | bool focused = sway_seat_get_focus(seat) == c; | 143 | bool focused = seat_get_focus(seat) == c; |
144 | 144 | ||
145 | json_object *object = json_object_new_object(); | 145 | json_object *object = json_object_new_object(); |
146 | 146 | ||
diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 869f1ed0..df5fb699 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c | |||
@@ -388,8 +388,8 @@ static void ipc_get_workspaces_callback(struct sway_container *workspace, | |||
388 | // override the default focused indicator because | 388 | // override the default focused indicator because |
389 | // it's set differently for the get_workspaces reply | 389 | // it's set differently for the get_workspaces reply |
390 | struct sway_seat *seat = | 390 | struct sway_seat *seat = |
391 | sway_input_manager_get_default_seat(input_manager); | 391 | input_manager_get_default_seat(input_manager); |
392 | struct sway_container *focused_ws = sway_seat_get_focus(seat); | 392 | struct sway_container *focused_ws = seat_get_focus(seat); |
393 | if (focused_ws != NULL && focused_ws->type != C_WORKSPACE) { | 393 | if (focused_ws != NULL && focused_ws->type != C_WORKSPACE) { |
394 | focused_ws = container_parent(focused_ws, C_WORKSPACE); | 394 | focused_ws = container_parent(focused_ws, C_WORKSPACE); |
395 | } | 395 | } |
@@ -399,7 +399,7 @@ static void ipc_get_workspaces_callback(struct sway_container *workspace, | |||
399 | json_object_new_boolean(focused)); | 399 | json_object_new_boolean(focused)); |
400 | json_object_array_add((json_object *)data, workspace_json); | 400 | json_object_array_add((json_object *)data, workspace_json); |
401 | 401 | ||
402 | focused_ws = sway_seat_get_focus_inactive(seat, workspace->parent); | 402 | focused_ws = seat_get_focus_inactive(seat, workspace->parent); |
403 | if (focused_ws->type != C_WORKSPACE) { | 403 | if (focused_ws->type != C_WORKSPACE) { |
404 | focused_ws = container_parent(focused_ws, C_WORKSPACE); | 404 | focused_ws = container_parent(focused_ws, C_WORKSPACE); |
405 | } | 405 | } |
diff --git a/sway/server.c b/sway/server.c index f5cc199c..54945312 100644 --- a/sway/server.c +++ b/sway/server.c | |||
@@ -109,7 +109,7 @@ bool server_init(struct sway_server *server) { | |||
109 | return false; | 109 | return false; |
110 | } | 110 | } |
111 | 111 | ||
112 | input_manager = sway_input_manager_create(server); | 112 | input_manager = input_manager_create(server); |
113 | return true; | 113 | return true; |
114 | } | 114 | } |
115 | 115 | ||
diff --git a/sway/tree/container.c b/sway/tree/container.c index 9205d929..4db93ce8 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -89,8 +89,8 @@ static struct sway_container *_container_destroy(struct sway_container *cont) { | |||
89 | // container_remove_child, which removes child from this container | 89 | // container_remove_child, which removes child from this container |
90 | while (cont->children != NULL && cont->children->length != 0) { | 90 | while (cont->children != NULL && cont->children->length != 0) { |
91 | struct sway_container *child = cont->children->items[0]; | 91 | struct sway_container *child = cont->children->items[0]; |
92 | container_remove_child(child); | ||
92 | container_destroy(child); | 93 | container_destroy(child); |
93 | list_del(cont->children, 0); | ||
94 | } | 94 | } |
95 | } | 95 | } |
96 | if (cont->marks) { | 96 | if (cont->marks) { |
@@ -172,7 +172,7 @@ struct sway_container *container_output_create( | |||
172 | struct sway_seat *seat = NULL; | 172 | struct sway_seat *seat = NULL; |
173 | wl_list_for_each(seat, &input_manager->seats, link) { | 173 | wl_list_for_each(seat, &input_manager->seats, link) { |
174 | if (!seat->has_focus) { | 174 | if (!seat->has_focus) { |
175 | sway_seat_set_focus(seat, ws); | 175 | seat_set_focus(seat, ws); |
176 | } | 176 | } |
177 | } | 177 | } |
178 | 178 | ||
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index bea15f8a..88463e3b 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c | |||
@@ -158,17 +158,17 @@ void container_move_to(struct sway_container *container, | |||
158 | } | 158 | } |
159 | wl_signal_emit(&container->events.reparent, old_parent); | 159 | wl_signal_emit(&container->events.reparent, old_parent); |
160 | if (container->type == C_WORKSPACE) { | 160 | if (container->type == C_WORKSPACE) { |
161 | struct sway_seat *seat = sway_input_manager_get_default_seat( | 161 | struct sway_seat *seat = input_manager_get_default_seat( |
162 | input_manager); | 162 | input_manager); |
163 | if (old_parent->children->length == 0) { | 163 | if (old_parent->children->length == 0) { |
164 | char *ws_name = workspace_next_name(old_parent->name); | 164 | char *ws_name = workspace_next_name(old_parent->name); |
165 | struct sway_container *ws = | 165 | struct sway_container *ws = |
166 | container_workspace_create(old_parent, ws_name); | 166 | container_workspace_create(old_parent, ws_name); |
167 | free(ws_name); | 167 | free(ws_name); |
168 | sway_seat_set_focus(seat, ws); | 168 | seat_set_focus(seat, ws); |
169 | } | 169 | } |
170 | container_sort_workspaces(new_parent); | 170 | container_sort_workspaces(new_parent); |
171 | sway_seat_set_focus(seat, new_parent); | 171 | seat_set_focus(seat, new_parent); |
172 | } | 172 | } |
173 | if (old_parent) { | 173 | if (old_parent) { |
174 | arrange_windows(old_parent, -1, -1); | 174 | arrange_windows(old_parent, -1, -1); |
@@ -275,8 +275,8 @@ void arrange_windows(struct sway_container *container, | |||
275 | struct wlr_box *area = &output->sway_output->usable_area; | 275 | struct wlr_box *area = &output->sway_output->usable_area; |
276 | wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d", | 276 | wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d", |
277 | area->width, area->height, area->x, area->y); | 277 | area->width, area->height, area->x, area->y); |
278 | container->width = area->width; | 278 | container->width = width = area->width; |
279 | container->height = area->height; | 279 | container->height = height = area->height; |
280 | container->x = x = area->x; | 280 | container->x = x = area->x; |
281 | container->y = y = area->y; | 281 | container->y = y = area->y; |
282 | wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f", | 282 | wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f", |
@@ -441,7 +441,7 @@ static struct sway_container *get_swayc_in_output_direction( | |||
441 | return NULL; | 441 | return NULL; |
442 | } | 442 | } |
443 | 443 | ||
444 | struct sway_container *ws = sway_seat_get_focus_inactive(seat, output); | 444 | struct sway_container *ws = seat_get_focus_inactive(seat, output); |
445 | if (ws->type != C_WORKSPACE) { | 445 | if (ws->type != C_WORKSPACE) { |
446 | ws = container_parent(ws, C_WORKSPACE); | 446 | ws = container_parent(ws, C_WORKSPACE); |
447 | } | 447 | } |
@@ -462,7 +462,7 @@ static struct sway_container *get_swayc_in_output_direction( | |||
462 | case MOVE_UP: | 462 | case MOVE_UP: |
463 | case MOVE_DOWN: { | 463 | case MOVE_DOWN: { |
464 | struct sway_container *focused = | 464 | struct sway_container *focused = |
465 | sway_seat_get_focus_inactive(seat, ws); | 465 | seat_get_focus_inactive(seat, ws); |
466 | if (focused && focused->parent) { | 466 | if (focused && focused->parent) { |
467 | struct sway_container *parent = focused->parent; | 467 | struct sway_container *parent = focused->parent; |
468 | if (parent->layout == L_VERT) { | 468 | if (parent->layout == L_VERT) { |
@@ -546,7 +546,7 @@ struct sway_container *container_get_in_direction( | |||
546 | struct sway_container *container, struct sway_seat *seat, | 546 | struct sway_container *container, struct sway_seat *seat, |
547 | enum movement_direction dir) { | 547 | enum movement_direction dir) { |
548 | if (dir == MOVE_CHILD) { | 548 | if (dir == MOVE_CHILD) { |
549 | return sway_seat_get_focus_inactive(seat, container); | 549 | return seat_get_focus_inactive(seat, container); |
550 | } | 550 | } |
551 | 551 | ||
552 | struct sway_container *parent = container->parent; | 552 | struct sway_container *parent = container->parent; |
@@ -605,7 +605,7 @@ struct sway_container *container_get_in_direction( | |||
605 | } | 605 | } |
606 | if (next->children && next->children->length) { | 606 | if (next->children && next->children->length) { |
607 | // TODO consider floating children as well | 607 | // TODO consider floating children as well |
608 | return sway_seat_get_focus_by_type(seat, next, C_VIEW); | 608 | return seat_get_focus_by_type(seat, next, C_VIEW); |
609 | } else { | 609 | } else { |
610 | return next; | 610 | return next; |
611 | } | 611 | } |
@@ -635,7 +635,7 @@ struct sway_container *container_get_in_direction( | |||
635 | wrap_candidate = parent->children->items[0]; | 635 | wrap_candidate = parent->children->items[0]; |
636 | } | 636 | } |
637 | if (config->force_focus_wrapping) { | 637 | if (config->force_focus_wrapping) { |
638 | return sway_seat_get_focus_by_type(seat, | 638 | return seat_get_focus_by_type(seat, |
639 | wrap_candidate, C_VIEW); | 639 | wrap_candidate, C_VIEW); |
640 | } | 640 | } |
641 | } | 641 | } |
@@ -643,7 +643,7 @@ struct sway_container *container_get_in_direction( | |||
643 | wlr_log(L_DEBUG, | 643 | wlr_log(L_DEBUG, |
644 | "cont %d-%p dir %i sibling %d: %p", idx, | 644 | "cont %d-%p dir %i sibling %d: %p", idx, |
645 | container, dir, desired, parent->children->items[desired]); | 645 | container, dir, desired, parent->children->items[desired]); |
646 | return sway_seat_get_focus_by_type(seat, | 646 | return seat_get_focus_by_type(seat, |
647 | parent->children->items[desired], C_VIEW); | 647 | parent->children->items[desired], C_VIEW); |
648 | } | 648 | } |
649 | } | 649 | } |
@@ -702,9 +702,9 @@ struct sway_container *container_split(struct sway_container *child, | |||
702 | cont->y = child->y; | 702 | cont->y = child->y; |
703 | 703 | ||
704 | if (child->type == C_WORKSPACE) { | 704 | if (child->type == C_WORKSPACE) { |
705 | struct sway_seat *seat = sway_input_manager_get_default_seat(input_manager); | 705 | struct sway_seat *seat = input_manager_get_default_seat(input_manager); |
706 | struct sway_container *workspace = child; | 706 | struct sway_container *workspace = child; |
707 | bool set_focus = (sway_seat_get_focus(seat) == workspace); | 707 | bool set_focus = (seat_get_focus(seat) == workspace); |
708 | 708 | ||
709 | while (workspace->children->length) { | 709 | while (workspace->children->length) { |
710 | struct sway_container *ws_child = workspace->children->items[0]; | 710 | struct sway_container *ws_child = workspace->children->items[0]; |
@@ -716,7 +716,7 @@ struct sway_container *container_split(struct sway_container *child, | |||
716 | container_set_layout(workspace, layout); | 716 | container_set_layout(workspace, layout); |
717 | 717 | ||
718 | if (set_focus) { | 718 | if (set_focus) { |
719 | sway_seat_set_focus(seat, cont); | 719 | seat_set_focus(seat, cont); |
720 | } | 720 | } |
721 | } else { | 721 | } else { |
722 | cont->layout = layout; | 722 | cont->layout = layout; |
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index de1bf159..74330884 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c | |||
@@ -158,7 +158,7 @@ static bool _workspace_by_name(struct sway_container *view, void *data) { | |||
158 | struct sway_container *workspace_by_name(const char *name) { | 158 | struct sway_container *workspace_by_name(const char *name) { |
159 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 159 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
160 | struct sway_container *current_workspace = NULL, *current_output = NULL; | 160 | struct sway_container *current_workspace = NULL, *current_output = NULL; |
161 | struct sway_container *focus = sway_seat_get_focus(seat); | 161 | struct sway_container *focus = seat_get_focus(seat); |
162 | if (focus) { | 162 | if (focus) { |
163 | current_workspace = container_parent(focus, C_WORKSPACE); | 163 | current_workspace = container_parent(focus, C_WORKSPACE); |
164 | current_output = container_parent(focus, C_OUTPUT); | 164 | current_output = container_parent(focus, C_OUTPUT); |
@@ -200,7 +200,7 @@ struct sway_container *workspace_create(const char *name) { | |||
200 | // Otherwise create a new one | 200 | // Otherwise create a new one |
201 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 201 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
202 | struct sway_container *focus = | 202 | struct sway_container *focus = |
203 | sway_seat_get_focus_inactive(seat, &root_container); | 203 | seat_get_focus_inactive(seat, &root_container); |
204 | parent = focus; | 204 | parent = focus; |
205 | parent = container_parent(parent, C_OUTPUT); | 205 | parent = container_parent(parent, C_OUTPUT); |
206 | struct sway_container *new_ws = container_workspace_create(parent, name); | 206 | struct sway_container *new_ws = container_workspace_create(parent, name); |
@@ -260,7 +260,7 @@ struct sway_container *workspace_output_prev_next_impl( | |||
260 | } | 260 | } |
261 | 261 | ||
262 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 262 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
263 | struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); | 263 | struct sway_container *focus = seat_get_focus_inactive(seat, output); |
264 | struct sway_container *workspace = (focus->type == C_WORKSPACE ? | 264 | struct sway_container *workspace = (focus->type == C_WORKSPACE ? |
265 | focus : | 265 | focus : |
266 | container_parent(focus, C_WORKSPACE)); | 266 | container_parent(focus, C_WORKSPACE)); |
@@ -345,7 +345,7 @@ bool workspace_switch(struct sway_container *workspace) { | |||
345 | } | 345 | } |
346 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 346 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
347 | struct sway_container *focus = | 347 | struct sway_container *focus = |
348 | sway_seat_get_focus_inactive(seat, &root_container); | 348 | seat_get_focus_inactive(seat, &root_container); |
349 | if (!seat || !focus) { | 349 | if (!seat || !focus) { |
350 | return false; | 350 | return false; |
351 | } | 351 | } |
@@ -376,11 +376,11 @@ bool workspace_switch(struct sway_container *workspace) { | |||
376 | 376 | ||
377 | wlr_log(L_DEBUG, "Switching to workspace %p:%s", | 377 | wlr_log(L_DEBUG, "Switching to workspace %p:%s", |
378 | workspace, workspace->name); | 378 | workspace, workspace->name); |
379 | struct sway_container *next = sway_seat_get_focus_inactive(seat, workspace); | 379 | struct sway_container *next = seat_get_focus_inactive(seat, workspace); |
380 | if (next == NULL) { | 380 | if (next == NULL) { |
381 | next = workspace; | 381 | next = workspace; |
382 | } | 382 | } |
383 | sway_seat_set_focus(seat, next); | 383 | seat_set_focus(seat, next); |
384 | struct sway_container *output = container_parent(workspace, C_OUTPUT); | 384 | struct sway_container *output = container_parent(workspace, C_OUTPUT); |
385 | arrange_windows(output, -1, -1); | 385 | arrange_windows(output, -1, -1); |
386 | return true; | 386 | return true; |
@@ -389,7 +389,7 @@ bool workspace_switch(struct sway_container *workspace) { | |||
389 | bool workspace_is_visible(struct sway_container *ws) { | 389 | bool workspace_is_visible(struct sway_container *ws) { |
390 | struct sway_container *output = container_parent(ws, C_OUTPUT); | 390 | struct sway_container *output = container_parent(ws, C_OUTPUT); |
391 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 391 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
392 | struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); | 392 | struct sway_container *focus = seat_get_focus_inactive(seat, output); |
393 | if (focus->type != C_WORKSPACE) { | 393 | if (focus->type != C_WORKSPACE) { |
394 | focus = container_parent(focus, C_WORKSPACE); | 394 | focus = container_parent(focus, C_WORKSPACE); |
395 | } | 395 | } |
diff --git a/swaybar/bar.c b/swaybar/bar.c index f743236c..fb417095 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c | |||
@@ -308,14 +308,14 @@ static void display_in(int fd, short mask, void *_bar) { | |||
308 | 308 | ||
309 | static void ipc_in(int fd, short mask, void *_bar) { | 309 | static void ipc_in(int fd, short mask, void *_bar) { |
310 | struct swaybar *bar = (struct swaybar *)_bar; | 310 | struct swaybar *bar = (struct swaybar *)_bar; |
311 | if (handle_ipc_event(bar)) { | 311 | if (handle_ipc_readable(bar)) { |
312 | render_all_frames(bar); | 312 | render_all_frames(bar); |
313 | } | 313 | } |
314 | } | 314 | } |
315 | 315 | ||
316 | static void status_in(int fd, short mask, void *_bar) { | 316 | static void status_in(int fd, short mask, void *_bar) { |
317 | struct swaybar *bar = (struct swaybar *)_bar; | 317 | struct swaybar *bar = (struct swaybar *)_bar; |
318 | if (handle_status_readable(bar->status)) { | 318 | if (status_handle_readable(bar->status)) { |
319 | render_all_frames(bar); | 319 | render_all_frames(bar); |
320 | } | 320 | } |
321 | } | 321 | } |
diff --git a/swaybar/i3bar.c b/swaybar/i3bar.c new file mode 100644 index 00000000..46459e24 --- /dev/null +++ b/swaybar/i3bar.c | |||
@@ -0,0 +1,208 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <json-c/json.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <string.h> | ||
5 | #include <unistd.h> | ||
6 | #include <wlr/util/log.h> | ||
7 | #include "swaybar/config.h" | ||
8 | #include "swaybar/status_line.h" | ||
9 | |||
10 | static void i3bar_block_free(struct i3bar_block *block) { | ||
11 | if (!block) { | ||
12 | return; | ||
13 | } | ||
14 | wl_list_remove(&block->link); | ||
15 | free(block->full_text); | ||
16 | free(block->short_text); | ||
17 | free(block->align); | ||
18 | free(block->name); | ||
19 | free(block->instance); | ||
20 | free(block->color); | ||
21 | } | ||
22 | |||
23 | static bool i3bar_parse_json(struct status_line *status, const char *text) { | ||
24 | struct i3bar_block *block, *tmp; | ||
25 | wl_list_for_each_safe(block, tmp, &status->blocks, link) { | ||
26 | i3bar_block_free(block); | ||
27 | } | ||
28 | json_object *results = json_tokener_parse(text); | ||
29 | if (!results) { | ||
30 | status_error(status, "[failed to parse i3bar json]"); | ||
31 | return false; | ||
32 | } | ||
33 | wlr_log(L_DEBUG, "Got i3bar json: '%s'", text); | ||
34 | for (size_t i = 0; i < json_object_array_length(results); ++i) { | ||
35 | json_object *full_text, *short_text, *color, *min_width, *align, *urgent; | ||
36 | json_object *name, *instance, *separator, *separator_block_width; | ||
37 | json_object *background, *border, *border_top, *border_bottom; | ||
38 | json_object *border_left, *border_right, *markup; | ||
39 | json_object *json = json_object_array_get_idx(results, i); | ||
40 | if (!json) { | ||
41 | continue; | ||
42 | } | ||
43 | json_object_object_get_ex(json, "full_text", &full_text); | ||
44 | json_object_object_get_ex(json, "short_text", &short_text); | ||
45 | json_object_object_get_ex(json, "color", &color); | ||
46 | json_object_object_get_ex(json, "min_width", &min_width); | ||
47 | json_object_object_get_ex(json, "align", &align); | ||
48 | json_object_object_get_ex(json, "urgent", &urgent); | ||
49 | json_object_object_get_ex(json, "name", &name); | ||
50 | json_object_object_get_ex(json, "instance", &instance); | ||
51 | json_object_object_get_ex(json, "markup", &markup); | ||
52 | json_object_object_get_ex(json, "separator", &separator); | ||
53 | json_object_object_get_ex(json, "separator_block_width", &separator_block_width); | ||
54 | json_object_object_get_ex(json, "background", &background); | ||
55 | json_object_object_get_ex(json, "border", &border); | ||
56 | json_object_object_get_ex(json, "border_top", &border_top); | ||
57 | json_object_object_get_ex(json, "border_bottom", &border_bottom); | ||
58 | json_object_object_get_ex(json, "border_left", &border_left); | ||
59 | json_object_object_get_ex(json, "border_right", &border_right); | ||
60 | |||
61 | struct i3bar_block *block = calloc(1, sizeof(struct i3bar_block)); | ||
62 | block->full_text = full_text ? | ||
63 | strdup(json_object_get_string(full_text)) : NULL; | ||
64 | block->short_text = short_text ? | ||
65 | strdup(json_object_get_string(short_text)) : NULL; | ||
66 | if (color) { | ||
67 | block->color = malloc(sizeof(uint32_t)); | ||
68 | *block->color = parse_color(json_object_get_string(color)); | ||
69 | } | ||
70 | if (min_width) { | ||
71 | json_type type = json_object_get_type(min_width); | ||
72 | if (type == json_type_int) { | ||
73 | block->min_width = json_object_get_int(min_width); | ||
74 | } else if (type == json_type_string) { | ||
75 | /* the width will be calculated when rendering */ | ||
76 | block->min_width = 0; | ||
77 | } | ||
78 | } | ||
79 | block->align = strdup(align ? json_object_get_string(align) : "left"); | ||
80 | block->urgent = urgent ? json_object_get_int(urgent) : false; | ||
81 | block->name = name ? strdup(json_object_get_string(name)) : NULL; | ||
82 | block->instance = instance ? | ||
83 | strdup(json_object_get_string(instance)) : NULL; | ||
84 | if (markup) { | ||
85 | block->markup = false; | ||
86 | const char *markup_str = json_object_get_string(markup); | ||
87 | if (strcmp(markup_str, "pango") == 0) { | ||
88 | block->markup = true; | ||
89 | } | ||
90 | } | ||
91 | block->separator = separator ? json_object_get_int(separator) : true; | ||
92 | block->separator_block_width = separator_block_width ? | ||
93 | json_object_get_int(separator_block_width) : 9; | ||
94 | // Airblader features | ||
95 | block->background = background ? | ||
96 | parse_color(json_object_get_string(background)) : 0; | ||
97 | block->border = border ? | ||
98 | parse_color(json_object_get_string(border)) : 0; | ||
99 | block->border_top = border_top ? json_object_get_int(border_top) : 1; | ||
100 | block->border_bottom = border_bottom ? | ||
101 | json_object_get_int(border_bottom) : 1; | ||
102 | block->border_left = border_left ? json_object_get_int(border_left) : 1; | ||
103 | block->border_right = border_right ? | ||
104 | json_object_get_int(border_right) : 1; | ||
105 | wl_list_insert(&status->blocks, &block->link); | ||
106 | } | ||
107 | return true; | ||
108 | } | ||
109 | |||
110 | bool i3bar_handle_readable(struct status_line *status) { | ||
111 | struct i3bar_protocol_state *state = &status->i3bar_state; | ||
112 | |||
113 | char *cur = &state->buffer[state->buffer_index]; | ||
114 | ssize_t n = read(status->read_fd, cur, | ||
115 | state->buffer_size - state->buffer_index); | ||
116 | if (n == 0) { | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | if (n == (ssize_t)(state->buffer_size - state->buffer_index)) { | ||
121 | state->buffer_size = state->buffer_size * 2; | ||
122 | char *new_buffer = realloc(state->buffer, state->buffer_size); | ||
123 | if (!new_buffer) { | ||
124 | free(state->buffer); | ||
125 | status_error(status, "[failed to allocate buffer]"); | ||
126 | return -1; | ||
127 | } | ||
128 | state->buffer = new_buffer; | ||
129 | } | ||
130 | |||
131 | bool redraw = false; | ||
132 | while (*cur) { | ||
133 | if (state->nodes[state->depth] == JSON_NODE_STRING) { | ||
134 | if (!state->escape && *cur == '"') { | ||
135 | --state->depth; | ||
136 | } | ||
137 | state->escape = !state->escape && *cur == '\\'; | ||
138 | } else { | ||
139 | switch (*cur) { | ||
140 | case '[': | ||
141 | ++state->depth; | ||
142 | if (state->depth > | ||
143 | sizeof(state->nodes) / sizeof(state->nodes[0])) { | ||
144 | status_error(status, "[i3bar json too deep]"); | ||
145 | return false; | ||
146 | } | ||
147 | state->nodes[state->depth] = JSON_NODE_ARRAY; | ||
148 | if (state->depth == 1) { | ||
149 | state->current_node = cur; | ||
150 | } | ||
151 | break; | ||
152 | case ']': | ||
153 | if (state->nodes[state->depth] != JSON_NODE_ARRAY) { | ||
154 | status_error(status, "[failed to parse i3bar json]"); | ||
155 | return false; | ||
156 | } | ||
157 | --state->depth; | ||
158 | if (state->depth == 0) { | ||
159 | // cur[1] is valid since cur[0] != '\0' | ||
160 | char p = cur[1]; | ||
161 | cur[1] = '\0'; | ||
162 | redraw = i3bar_parse_json( | ||
163 | status, state->current_node) || redraw; | ||
164 | cur[1] = p; | ||
165 | memmove(state->buffer, cur, | ||
166 | state->buffer_size - (cur - state->buffer)); | ||
167 | cur = state->buffer; | ||
168 | state->current_node = cur + 1; | ||
169 | } | ||
170 | break; | ||
171 | case '"': | ||
172 | ++state->depth; | ||
173 | if (state->depth > | ||
174 | sizeof(state->nodes) / sizeof(state->nodes[0])) { | ||
175 | status_error(status, "[i3bar json too deep]"); | ||
176 | return false; | ||
177 | } | ||
178 | state->nodes[state->depth] = JSON_NODE_STRING; | ||
179 | break; | ||
180 | } | ||
181 | } | ||
182 | ++cur; | ||
183 | } | ||
184 | state->buffer_index = cur - state->buffer; | ||
185 | return redraw; | ||
186 | } | ||
187 | |||
188 | void i3bar_block_send_click(struct status_line *status, | ||
189 | struct i3bar_block *block, int x, int y, uint32_t button) { | ||
190 | wlr_log(L_DEBUG, "block %s clicked", block->name ? block->name : "(nil)"); | ||
191 | if (!block->name || !status->i3bar_state.click_events) { | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | struct json_object *event_json = json_object_new_object(); | ||
196 | json_object_object_add(event_json, "name", | ||
197 | json_object_new_string(block->name)); | ||
198 | if (block->instance) { | ||
199 | json_object_object_add(event_json, "instance", | ||
200 | json_object_new_string(block->instance)); | ||
201 | } | ||
202 | |||
203 | json_object_object_add(event_json, "button", json_object_new_int(button)); | ||
204 | json_object_object_add(event_json, "x", json_object_new_int(x)); | ||
205 | json_object_object_add(event_json, "y", json_object_new_int(y)); | ||
206 | dprintf(status->write_fd, "%s\n", json_object_to_json_string(event_json)); | ||
207 | json_object_put(event_json); | ||
208 | } | ||
diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 64583df0..ed5d9a31 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c | |||
@@ -323,7 +323,7 @@ void ipc_initialize(struct swaybar *bar, const char *bar_id) { | |||
323 | IPC_SUBSCRIBE, subscribe, &len)); | 323 | IPC_SUBSCRIBE, subscribe, &len)); |
324 | } | 324 | } |
325 | 325 | ||
326 | bool handle_ipc_event(struct swaybar *bar) { | 326 | bool handle_ipc_readable(struct swaybar *bar) { |
327 | struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd); | 327 | struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd); |
328 | if (!resp) { | 328 | if (!resp) { |
329 | return false; | 329 | return false; |
diff --git a/swaybar/meson.build b/swaybar/meson.build index bf6f6d7a..d65edb11 100644 --- a/swaybar/meson.build +++ b/swaybar/meson.build | |||
@@ -3,6 +3,7 @@ executable( | |||
3 | 'bar.c', | 3 | 'bar.c', |
4 | 'config.c', | 4 | 'config.c', |
5 | 'event_loop.c', | 5 | 'event_loop.c', |
6 | 'i3bar.c', | ||
6 | 'ipc.c', | 7 | 'ipc.c', |
7 | 'main.c', | 8 | 'main.c', |
8 | 'render.c', | 9 | 'render.c', |
diff --git a/swaybar/render.c b/swaybar/render.c index c2358724..6f3b0788 100644 --- a/swaybar/render.c +++ b/swaybar/render.c | |||
@@ -18,10 +18,33 @@ static const int ws_horizontal_padding = 5; | |||
18 | static const double ws_vertical_padding = 1.5; | 18 | static const double ws_vertical_padding = 1.5; |
19 | static const double border_width = 1; | 19 | static const double border_width = 1; |
20 | 20 | ||
21 | static uint32_t render_status_line_error(cairo_t *cairo, | ||
22 | struct swaybar_config *config, const char *error, | ||
23 | double *x, uint32_t width, uint32_t height) { | ||
24 | if (!error) { | ||
25 | return 0; | ||
26 | } | ||
27 | cairo_set_source_u32(cairo, 0xFF0000FF); | ||
28 | static const int margin = 3; | ||
29 | int text_width, text_height; | ||
30 | get_text_size(cairo, config->font, | ||
31 | &text_width, &text_height, 1, false, "%s", error); | ||
32 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | ||
33 | if (height < ideal_height) { | ||
34 | return ideal_height; | ||
35 | } | ||
36 | *x -= text_width + margin; | ||
37 | double text_y = height / 2.0 - text_height / 2.0; | ||
38 | cairo_move_to(cairo, *x, (int)floor(text_y)); | ||
39 | pango_printf(cairo, config->font, 1, false, "%s", error); | ||
40 | *x -= margin; | ||
41 | return ideal_height; | ||
42 | } | ||
43 | |||
21 | static uint32_t render_status_line_text(cairo_t *cairo, | 44 | static uint32_t render_status_line_text(cairo_t *cairo, |
22 | struct swaybar_config *config, struct status_line *status, | 45 | struct swaybar_config *config, const char *text, |
23 | bool focused, uint32_t width, uint32_t height) { | 46 | bool focused, double *x, uint32_t width, uint32_t height) { |
24 | if (!status->text) { | 47 | if (!text) { |
25 | return 0; | 48 | return 0; |
26 | } | 49 | } |
27 | cairo_set_source_u32(cairo, focused ? | 50 | cairo_set_source_u32(cairo, focused ? |
@@ -29,38 +52,211 @@ static uint32_t render_status_line_text(cairo_t *cairo, | |||
29 | static const int margin = 3; | 52 | static const int margin = 3; |
30 | int text_width, text_height; | 53 | int text_width, text_height; |
31 | get_text_size(cairo, config->font, &text_width, &text_height, | 54 | get_text_size(cairo, config->font, &text_width, &text_height, |
32 | 1, config->pango_markup, "%s", status->text); | 55 | 1, config->pango_markup, "%s", text); |
33 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | 56 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; |
34 | if (height < ideal_height) { | 57 | if (height < ideal_height) { |
35 | return ideal_height; | 58 | return ideal_height; |
36 | } | 59 | } |
60 | *x -= text_width + margin; | ||
37 | double text_y = height / 2.0 - text_height / 2.0; | 61 | double text_y = height / 2.0 - text_height / 2.0; |
38 | cairo_move_to(cairo, width - text_width - margin, (int)floor(text_y)); | 62 | cairo_move_to(cairo, *x, (int)floor(text_y)); |
39 | pango_printf(cairo, config->font, 1, config->pango_markup, | 63 | pango_printf(cairo, config->font, 1, config->pango_markup, "%s", text); |
40 | "%s", status->text); | 64 | *x -= margin; |
65 | return ideal_height; | ||
66 | } | ||
67 | |||
68 | static void render_sharp_line(cairo_t *cairo, uint32_t color, | ||
69 | double x, double y, double width, double height) { | ||
70 | cairo_set_source_u32(cairo, color); | ||
71 | if (width > 1 && height > 1) { | ||
72 | cairo_rectangle(cairo, x, y, width, height); | ||
73 | cairo_fill(cairo); | ||
74 | } else { | ||
75 | if (width == 1) { | ||
76 | x += 0.5; | ||
77 | height += y; | ||
78 | width = x; | ||
79 | } | ||
80 | if (height == 1) { | ||
81 | y += 0.5; | ||
82 | width += x; | ||
83 | height = y; | ||
84 | } | ||
85 | cairo_move_to(cairo, x, y); | ||
86 | cairo_set_line_width(cairo, 1.0); | ||
87 | cairo_line_to(cairo, width, height); | ||
88 | cairo_stroke(cairo); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | static void block_hotspot_callback(struct swaybar_output *output, | ||
93 | int x, int y, uint32_t button, void *data) { | ||
94 | struct i3bar_block *block = data; | ||
95 | struct status_line *status = output->bar->status; | ||
96 | i3bar_block_send_click(status, block, x, y, button); | ||
97 | } | ||
98 | |||
99 | static uint32_t render_status_block(cairo_t *cairo, | ||
100 | struct swaybar_config *config, struct swaybar_output *output, | ||
101 | struct i3bar_block *block, double *x, | ||
102 | uint32_t height, bool focused, bool edge) { | ||
103 | static const int margin = 3; | ||
104 | if (!block->full_text || !*block->full_text) { | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | int text_width, text_height; | ||
109 | get_text_size(cairo, config->font, &text_width, &text_height, | ||
110 | 1, block->markup, "%s", block->full_text); | ||
111 | int width = text_width; | ||
112 | if (width < block->min_width) { | ||
113 | width = block->min_width; | ||
114 | } | ||
115 | double block_width = width; | ||
116 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | ||
117 | if (height < ideal_height) { | ||
118 | return ideal_height; | ||
119 | } | ||
120 | |||
121 | *x -= width; | ||
122 | if (block->border && block->border_left > 0) { | ||
123 | *x -= (block->border_left + margin); | ||
124 | block_width += block->border_left + margin; | ||
125 | } | ||
126 | if (block->border && block->border_right > 0) { | ||
127 | *x -= (block->border_right + margin); | ||
128 | block_width += block->border_right + margin; | ||
129 | } | ||
130 | |||
131 | int sep_width; | ||
132 | if (!edge) { | ||
133 | if (config->sep_symbol) { | ||
134 | int _height; | ||
135 | get_text_size(cairo, config->font, &sep_width, &_height, | ||
136 | 1, false, "%s", config->sep_symbol); | ||
137 | uint32_t _ideal_height = _height + ws_vertical_padding * 2; | ||
138 | if (height < _ideal_height) { | ||
139 | return _height; | ||
140 | } | ||
141 | if (sep_width > block->separator_block_width) { | ||
142 | block->separator_block_width = sep_width + margin * 2; | ||
143 | } | ||
144 | } | ||
145 | *x -= block->separator_block_width; | ||
146 | } else { | ||
147 | *x -= margin; | ||
148 | } | ||
149 | |||
150 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); | ||
151 | hotspot->x = *x; | ||
152 | hotspot->y = 0; | ||
153 | hotspot->width = width; | ||
154 | hotspot->height = height; | ||
155 | hotspot->callback = block_hotspot_callback; | ||
156 | hotspot->destroy = NULL; | ||
157 | hotspot->data = block; | ||
158 | wl_list_insert(&output->hotspots, &hotspot->link); | ||
159 | |||
160 | double pos = *x; | ||
161 | if (block->background) { | ||
162 | cairo_set_source_u32(cairo, block->background); | ||
163 | cairo_rectangle(cairo, pos - 0.5, 1, block_width, height); | ||
164 | cairo_fill(cairo); | ||
165 | } | ||
166 | |||
167 | if (block->border && block->border_top > 0) { | ||
168 | render_sharp_line(cairo, block->border, | ||
169 | pos - 0.5, 1, block_width, block->border_top); | ||
170 | } | ||
171 | if (block->border && block->border_bottom > 0) { | ||
172 | render_sharp_line(cairo, block->border, | ||
173 | pos - 0.5, height - 1 - block->border_bottom, | ||
174 | block_width, block->border_bottom); | ||
175 | } | ||
176 | if (block->border != 0 && block->border_left > 0) { | ||
177 | render_sharp_line(cairo, block->border, | ||
178 | pos - 0.5, 1, block->border_left, height); | ||
179 | pos += block->border_left + margin; | ||
180 | } | ||
181 | |||
182 | double offset = 0; | ||
183 | if (strncmp(block->align, "left", 5) == 0) { | ||
184 | offset = pos; | ||
185 | } else if (strncmp(block->align, "right", 5) == 0) { | ||
186 | offset = pos + width - text_width; | ||
187 | } else if (strncmp(block->align, "center", 6) == 0) { | ||
188 | offset = pos + (width - text_width) / 2; | ||
189 | } | ||
190 | cairo_move_to(cairo, offset, height / 2.0 - text_height / 2.0); | ||
191 | uint32_t color = block->color ? *block->color : config->colors.statusline; | ||
192 | cairo_set_source_u32(cairo, color); | ||
193 | pango_printf(cairo, config->font, 1, block->markup, "%s", block->full_text); | ||
194 | pos += width; | ||
195 | |||
196 | if (block->border && block->border_right > 0) { | ||
197 | pos += margin; | ||
198 | render_sharp_line(cairo, block->border, | ||
199 | pos - 0.5, 1, block->border_right, height); | ||
200 | pos += block->border_right; | ||
201 | } | ||
202 | |||
203 | if (!edge && block->separator) { | ||
204 | if (focused) { | ||
205 | cairo_set_source_u32(cairo, config->colors.focused_separator); | ||
206 | } else { | ||
207 | cairo_set_source_u32(cairo, config->colors.separator); | ||
208 | } | ||
209 | if (config->sep_symbol) { | ||
210 | offset = pos + (block->separator_block_width - sep_width) / 2; | ||
211 | cairo_move_to(cairo, offset, margin); | ||
212 | pango_printf(cairo, config->font, 1, false, | ||
213 | "%s", config->sep_symbol); | ||
214 | } else { | ||
215 | cairo_set_line_width(cairo, 1); | ||
216 | cairo_move_to(cairo, | ||
217 | pos + block->separator_block_width / 2, margin); | ||
218 | cairo_line_to(cairo, | ||
219 | pos + block->separator_block_width / 2, height - margin); | ||
220 | cairo_stroke(cairo); | ||
221 | } | ||
222 | } | ||
41 | return ideal_height; | 223 | return ideal_height; |
42 | } | 224 | } |
43 | 225 | ||
44 | static uint32_t render_status_line_i3bar(cairo_t *cairo, | 226 | static uint32_t render_status_line_i3bar(cairo_t *cairo, |
45 | struct swaybar_config *config, struct status_line *status, | 227 | struct swaybar_config *config, struct swaybar_output *output, |
46 | bool focused, uint32_t width, uint32_t height) { | 228 | struct status_line *status, bool focused, |
47 | // TODO | 229 | double *x, uint32_t width, uint32_t height) { |
48 | return 0; | 230 | uint32_t max_height = 0; |
231 | bool edge = true; | ||
232 | struct i3bar_block *block; | ||
233 | wl_list_for_each(block, &status->blocks, link) { | ||
234 | uint32_t h = render_status_block(cairo, config, output, | ||
235 | block, x, height, focused, edge); | ||
236 | max_height = h > max_height ? h : max_height; | ||
237 | edge = false; | ||
238 | } | ||
239 | return max_height; | ||
49 | } | 240 | } |
50 | 241 | ||
51 | static uint32_t render_status_line(cairo_t *cairo, | 242 | static uint32_t render_status_line(cairo_t *cairo, |
52 | struct swaybar_config *config, struct status_line *status, | 243 | struct swaybar_config *config, struct swaybar_output *output, |
53 | bool focused, uint32_t width, uint32_t height) { | 244 | struct status_line *status, bool focused, |
245 | double *x, uint32_t width, uint32_t height) { | ||
54 | switch (status->protocol) { | 246 | switch (status->protocol) { |
247 | case PROTOCOL_ERROR: | ||
248 | return render_status_line_error(cairo, | ||
249 | config, status->text, x, width, height); | ||
55 | case PROTOCOL_TEXT: | 250 | case PROTOCOL_TEXT: |
56 | return render_status_line_text(cairo, | 251 | return render_status_line_text(cairo, |
57 | config, status, focused, width, height); | 252 | config, status->text, focused, x, width, height); |
58 | case PROTOCOL_I3BAR: | 253 | case PROTOCOL_I3BAR: |
59 | return render_status_line_i3bar(cairo, | 254 | return render_status_line_i3bar(cairo, config, output, status, |
60 | config, status, focused, width, height); | 255 | focused, x, width, height); |
61 | default: | 256 | case PROTOCOL_UNDEF: |
62 | return 0; | 257 | return 0; |
63 | } | 258 | } |
259 | return 0; | ||
64 | } | 260 | } |
65 | 261 | ||
66 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, | 262 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, |
@@ -166,8 +362,8 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
166 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); | 362 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); |
167 | hotspot->x = *x; | 363 | hotspot->x = *x; |
168 | hotspot->y = 0; | 364 | hotspot->y = 0; |
169 | hotspot->height = height; | ||
170 | hotspot->width = width; | 365 | hotspot->width = width; |
366 | hotspot->height = height; | ||
171 | hotspot->callback = workspace_hotspot_callback; | 367 | hotspot->callback = workspace_hotspot_callback; |
172 | hotspot->destroy = free; | 368 | hotspot->destroy = free; |
173 | hotspot->data = strdup(name); | 369 | hotspot->data = strdup(name); |
@@ -180,6 +376,7 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
180 | static uint32_t render_to_cairo(cairo_t *cairo, | 376 | static uint32_t render_to_cairo(cairo_t *cairo, |
181 | struct swaybar *bar, struct swaybar_output *output) { | 377 | struct swaybar *bar, struct swaybar_output *output) { |
182 | struct swaybar_config *config = bar->config; | 378 | struct swaybar_config *config = bar->config; |
379 | wlr_log(L_DEBUG, "output %p", output); | ||
183 | 380 | ||
184 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | 381 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); |
185 | if (output->focused) { | 382 | if (output->focused) { |
@@ -211,9 +408,10 @@ static uint32_t render_to_cairo(cairo_t *cairo, | |||
211 | cairo, config, config->mode, x, output->height); | 408 | cairo, config, config->mode, x, output->height); |
212 | max_height = h > max_height ? h : max_height; | 409 | max_height = h > max_height ? h : max_height; |
213 | } | 410 | } |
411 | x = output->width; | ||
214 | if (bar->status) { | 412 | if (bar->status) { |
215 | uint32_t h = render_status_line(cairo, config, bar->status, | 413 | uint32_t h = render_status_line(cairo, config, output, bar->status, |
216 | output->focused, output->width, output->height); | 414 | output->focused, &x, output->width, output->height); |
217 | max_height = h > max_height ? h : max_height; | 415 | max_height = h > max_height ? h : max_height; |
218 | } | 416 | } |
219 | 417 | ||
diff --git a/swaybar/status_line.c b/swaybar/status_line.c index 3454f207..cc7e217f 100644 --- a/swaybar/status_line.c +++ b/swaybar/status_line.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #define _POSIX_C_SOURCE | 1 | #define _POSIX_C_SOURCE |
2 | #include <fcntl.h> | 2 | #include <fcntl.h> |
3 | #include <json-c/json.h> | ||
3 | #include <stdlib.h> | 4 | #include <stdlib.h> |
4 | #include <string.h> | 5 | #include <string.h> |
5 | #include <stdio.h> | 6 | #include <stdio.h> |
@@ -9,35 +10,79 @@ | |||
9 | #include "swaybar/status_line.h" | 10 | #include "swaybar/status_line.h" |
10 | #include "readline.h" | 11 | #include "readline.h" |
11 | 12 | ||
12 | bool handle_status_readable(struct status_line *status) { | 13 | void status_error(struct status_line *status, const char *text) { |
13 | char *line = read_line_buffer(status->read, | 14 | close(status->read_fd); |
14 | status->buffer, status->buffer_size); | 15 | close(status->write_fd); |
16 | status->protocol = PROTOCOL_ERROR; | ||
17 | status->text = text; | ||
18 | } | ||
19 | |||
20 | bool status_handle_readable(struct status_line *status) { | ||
21 | char *line; | ||
15 | switch (status->protocol) { | 22 | switch (status->protocol) { |
23 | case PROTOCOL_ERROR: | ||
24 | return false; | ||
16 | case PROTOCOL_I3BAR: | 25 | case PROTOCOL_I3BAR: |
17 | // TODO | 26 | if (i3bar_handle_readable(status) > 0) { |
27 | return true; | ||
28 | } | ||
18 | break; | 29 | break; |
19 | case PROTOCOL_TEXT: | 30 | case PROTOCOL_TEXT: |
20 | status->text = line; | 31 | line = read_line_buffer(status->read, |
32 | status->text_state.buffer, status->text_state.buffer_size); | ||
33 | if (!line) { | ||
34 | status_error(status, "[error reading from status command]"); | ||
35 | } else { | ||
36 | status->text = line; | ||
37 | } | ||
21 | return true; | 38 | return true; |
22 | case PROTOCOL_UNDEF: | 39 | case PROTOCOL_UNDEF: |
40 | line = read_line_buffer(status->read, | ||
41 | status->text_state.buffer, status->text_state.buffer_size); | ||
23 | if (!line) { | 42 | if (!line) { |
43 | status_error(status, "[error reading from status command]"); | ||
24 | return false; | 44 | return false; |
25 | } | 45 | } |
26 | if (line[0] == '{') { | 46 | if (line[0] == '{') { |
27 | // TODO: JSON | 47 | json_object *proto = json_tokener_parse(line); |
48 | if (proto) { | ||
49 | json_object *version; | ||
50 | if (json_object_object_get_ex(proto, "version", &version) | ||
51 | && json_object_get_int(version) == 1) { | ||
52 | wlr_log(L_DEBUG, "Switched to i3bar protocol."); | ||
53 | status->protocol = PROTOCOL_I3BAR; | ||
54 | } | ||
55 | json_object *click_events; | ||
56 | if (json_object_object_get_ex( | ||
57 | proto, "click_events", &click_events) | ||
58 | && json_object_get_boolean(click_events)) { | ||
59 | wlr_log(L_DEBUG, "Enabled click events."); | ||
60 | status->i3bar_state.click_events = true; | ||
61 | const char *events_array = "[\n"; | ||
62 | write(status->write_fd, events_array, strlen(events_array)); | ||
63 | } | ||
64 | json_object_put(proto); | ||
65 | } | ||
66 | |||
67 | status->protocol = PROTOCOL_I3BAR; | ||
68 | free(status->text_state.buffer); | ||
69 | wl_list_init(&status->blocks); | ||
70 | status->i3bar_state.buffer_size = 4096; | ||
71 | status->i3bar_state.buffer = | ||
72 | malloc(status->i3bar_state.buffer_size); | ||
28 | } else { | 73 | } else { |
29 | status->text = line; | ||
30 | status->protocol = PROTOCOL_TEXT; | 74 | status->protocol = PROTOCOL_TEXT; |
75 | status->text = line; | ||
31 | } | 76 | } |
32 | return false; | 77 | return true; |
33 | } | 78 | } |
34 | return false; | 79 | return false; |
35 | } | 80 | } |
36 | 81 | ||
37 | struct status_line *status_line_init(char *cmd) { | 82 | struct status_line *status_line_init(char *cmd) { |
38 | struct status_line *status = calloc(1, sizeof(struct status_line)); | 83 | struct status_line *status = calloc(1, sizeof(struct status_line)); |
39 | status->buffer_size = 4096; | 84 | status->text_state.buffer_size = 8192; |
40 | status->buffer = malloc(status->buffer_size); | 85 | status->text_state.buffer = malloc(status->text_state.buffer_size); |
41 | 86 | ||
42 | int pipe_read_fd[2]; | 87 | int pipe_read_fd[2]; |
43 | int pipe_write_fd[2]; | 88 | int pipe_write_fd[2]; |