diff options
Diffstat (limited to 'sway')
87 files changed, 594 insertions, 263 deletions
diff --git a/sway/commands.c b/sway/commands.c index 55eda183..8d003dfa 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809 | ||
2 | #include <ctype.h> | 1 | #include <ctype.h> |
3 | #include <stdarg.h> | 2 | #include <stdarg.h> |
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
@@ -82,7 +81,6 @@ static const struct cmd_handler handlers[] = { | |||
82 | { "no_focus", cmd_no_focus }, | 81 | { "no_focus", cmd_no_focus }, |
83 | { "output", cmd_output }, | 82 | { "output", cmd_output }, |
84 | { "popup_during_fullscreen", cmd_popup_during_fullscreen }, | 83 | { "popup_during_fullscreen", cmd_popup_during_fullscreen }, |
85 | { "primary_selection", cmd_primary_selection }, | ||
86 | { "seat", cmd_seat }, | 84 | { "seat", cmd_seat }, |
87 | { "set", cmd_set }, | 85 | { "set", cmd_set }, |
88 | { "show_marks", cmd_show_marks }, | 86 | { "show_marks", cmd_show_marks }, |
@@ -105,6 +103,7 @@ static const struct cmd_handler handlers[] = { | |||
105 | static const struct cmd_handler config_handlers[] = { | 103 | static const struct cmd_handler config_handlers[] = { |
106 | { "default_orientation", cmd_default_orientation }, | 104 | { "default_orientation", cmd_default_orientation }, |
107 | { "include", cmd_include }, | 105 | { "include", cmd_include }, |
106 | { "primary_selection", cmd_primary_selection }, | ||
108 | { "swaybg_command", cmd_swaybg_command }, | 107 | { "swaybg_command", cmd_swaybg_command }, |
109 | { "swaynag_command", cmd_swaynag_command }, | 108 | { "swaynag_command", cmd_swaynag_command }, |
110 | { "workspace_layout", cmd_workspace_layout }, | 109 | { "workspace_layout", cmd_workspace_layout }, |
diff --git a/sway/commands/assign.c b/sway/commands/assign.c index f7d911f7..bf95cf00 100644 --- a/sway/commands/assign.c +++ b/sway/commands/assign.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdio.h> | 1 | #include <stdio.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/bar.c b/sway/commands/bar.c index 22756acb..635e895b 100644 --- a/sway/commands/bar.c +++ b/sway/commands/bar.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809 | ||
2 | #include <stdio.h> | 1 | #include <stdio.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include <strings.h> | 3 | #include <strings.h> |
diff --git a/sway/commands/bar/font.c b/sway/commands/bar/font.c index 891c87af..0c074679 100644 --- a/sway/commands/bar/font.c +++ b/sway/commands/bar/font.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/bar/hidden_state.c b/sway/commands/bar/hidden_state.c index 8b661e3a..7b38831e 100644 --- a/sway/commands/bar/hidden_state.c +++ b/sway/commands/bar/hidden_state.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include <strings.h> | 2 | #include <strings.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/bar/icon_theme.c b/sway/commands/bar/icon_theme.c index 6ac07843..fee21709 100644 --- a/sway/commands/bar/icon_theme.c +++ b/sway/commands/bar/icon_theme.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "config.h" | 2 | #include "config.h" |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/bar/id.c b/sway/commands/bar/id.c index a9a61743..46cf4ca9 100644 --- a/sway/commands/bar/id.c +++ b/sway/commands/bar/id.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/bar/mode.c b/sway/commands/bar/mode.c index 7c2f423b..d69e910b 100644 --- a/sway/commands/bar/mode.c +++ b/sway/commands/bar/mode.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include <strings.h> | 2 | #include <strings.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/bar/output.c b/sway/commands/bar/output.c index cac1d056..51730176 100644 --- a/sway/commands/bar/output.c +++ b/sway/commands/bar/output.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdbool.h> | 1 | #include <stdbool.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/bar/position.c b/sway/commands/bar/position.c index b207de0b..94f530ec 100644 --- a/sway/commands/bar/position.c +++ b/sway/commands/bar/position.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include <strings.h> | 2 | #include <strings.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/bar/separator_symbol.c b/sway/commands/bar/separator_symbol.c index 6737d4d2..50e9a873 100644 --- a/sway/commands/bar/separator_symbol.c +++ b/sway/commands/bar/separator_symbol.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/bar/tray_output.c b/sway/commands/bar/tray_output.c index eb3b486e..679facf7 100644 --- a/sway/commands/bar/tray_output.c +++ b/sway/commands/bar/tray_output.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "config.h" | 2 | #include "config.h" |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/bind.c b/sway/commands/bind.c index 979e178f..268f2855 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <libevdev/libevdev.h> | 1 | #include <libevdev/libevdev.h> |
3 | #include <linux/input-event-codes.h> | 2 | #include <linux/input-event-codes.h> |
4 | #include <string.h> | 3 | #include <string.h> |
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c index 8fca1909..8bc1048c 100644 --- a/sway/commands/exec_always.c +++ b/sway/commands/exec_always.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdlib.h> | 1 | #include <stdlib.h> |
3 | #include <stdint.h> | 2 | #include <stdint.h> |
4 | #include <string.h> | 3 | #include <string.h> |
diff --git a/sway/commands/font.c b/sway/commands/font.c index 74bb6b9f..9920d03e 100644 --- a/sway/commands/font.c +++ b/sway/commands/font.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/gesture.c b/sway/commands/gesture.c index d4442cc3..90a20716 100644 --- a/sway/commands/gesture.c +++ b/sway/commands/gesture.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | 2 | ||
4 | #include "gesture.h" | 3 | #include "gesture.h" |
diff --git a/sway/commands/input/calibration_matrix.c b/sway/commands/input/calibration_matrix.c index 38749fbb..53fe2c35 100644 --- a/sway/commands/input/calibration_matrix.c +++ b/sway/commands/input/calibration_matrix.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include <strings.h> | 2 | #include <strings.h> |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/input/map_from_region.c b/sway/commands/input/map_from_region.c index 4400e111..2f8f753d 100644 --- a/sway/commands/input/map_from_region.c +++ b/sway/commands/input/map_from_region.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdbool.h> | 1 | #include <stdbool.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include <strings.h> | 3 | #include <strings.h> |
diff --git a/sway/commands/input/map_to_output.c b/sway/commands/input/map_to_output.c index f60fb7d5..a7266baa 100644 --- a/sway/commands/input/map_to_output.c +++ b/sway/commands/input/map_to_output.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include <strings.h> | 2 | #include <strings.h> |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/input/map_to_region.c b/sway/commands/input/map_to_region.c index ad535db2..9087c589 100644 --- a/sway/commands/input/map_to_region.c +++ b/sway/commands/input/map_to_region.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdlib.h> | 1 | #include <stdlib.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/input/xkb_file.c b/sway/commands/input/xkb_file.c index 493f94fb..056f00e5 100644 --- a/sway/commands/input/xkb_file.c +++ b/sway/commands/input/xkb_file.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <unistd.h> | 1 | #include <unistd.h> |
3 | #include <errno.h> | 2 | #include <errno.h> |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/input/xkb_layout.c b/sway/commands/input/xkb_layout.c index 22626517..1d01886c 100644 --- a/sway/commands/input/xkb_layout.c +++ b/sway/commands/input/xkb_layout.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/input/xkb_model.c b/sway/commands/input/xkb_model.c index f4a33de3..a9144a8a 100644 --- a/sway/commands/input/xkb_model.c +++ b/sway/commands/input/xkb_model.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/input/xkb_numlock.c b/sway/commands/input/xkb_numlock.c index 87d3e60c..bbe848fe 100644 --- a/sway/commands/input/xkb_numlock.c +++ b/sway/commands/input/xkb_numlock.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "util.h" | 3 | #include "util.h" |
diff --git a/sway/commands/input/xkb_options.c b/sway/commands/input/xkb_options.c index d609293f..7ca20777 100644 --- a/sway/commands/input/xkb_options.c +++ b/sway/commands/input/xkb_options.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/input/xkb_rules.c b/sway/commands/input/xkb_rules.c index 3b59622c..8fbd26fb 100644 --- a/sway/commands/input/xkb_rules.c +++ b/sway/commands/input/xkb_rules.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/input/xkb_switch_layout.c b/sway/commands/input/xkb_switch_layout.c index 3cce4ec8..ecac8e6c 100644 --- a/sway/commands/input/xkb_switch_layout.c +++ b/sway/commands/input/xkb_switch_layout.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <wlr/interfaces/wlr_keyboard.h> | 2 | #include <wlr/interfaces/wlr_keyboard.h> |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/input/xkb_variant.c b/sway/commands/input/xkb_variant.c index d0e21d77..2d14ea9c 100644 --- a/sway/commands/input/xkb_variant.c +++ b/sway/commands/input/xkb_variant.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/mark.c b/sway/commands/mark.c index 30cf458c..2bfc86b3 100644 --- a/sway/commands/mark.c +++ b/sway/commands/mark.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/mode.c b/sway/commands/mode.c index 7263efcb..b3216967 100644 --- a/sway/commands/mode.c +++ b/sway/commands/mode.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdbool.h> | 1 | #include <stdbool.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/move.c b/sway/commands/move.c index 69ed06c0..8addf26e 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <ctype.h> | 1 | #include <ctype.h> |
3 | #include <math.h> | 2 | #include <math.h> |
4 | #include <stdbool.h> | 3 | #include <stdbool.h> |
@@ -770,15 +769,6 @@ static struct cmd_results *cmd_move_in_direction( | |||
770 | ipc_event_window(container, "move"); | 769 | ipc_event_window(container, "move"); |
771 | } | 770 | } |
772 | 771 | ||
773 | // Hack to re-focus container | ||
774 | seat_set_raw_focus(config->handler_context.seat, &new_ws->node); | ||
775 | seat_set_focus_container(config->handler_context.seat, container); | ||
776 | |||
777 | if (old_ws != new_ws) { | ||
778 | ipc_event_workspace(old_ws, new_ws, "focus"); | ||
779 | workspace_detect_urgent(old_ws); | ||
780 | workspace_detect_urgent(new_ws); | ||
781 | } | ||
782 | container_end_mouse_operation(container); | 772 | container_end_mouse_operation(container); |
783 | 773 | ||
784 | return cmd_results_new(CMD_SUCCESS, NULL); | 774 | return cmd_results_new(CMD_SUCCESS, NULL); |
diff --git a/sway/commands/output.c b/sway/commands/output.c index df32c673..462dffd2 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c | |||
@@ -111,7 +111,10 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
111 | if (!config->reloading && !config->validating) { | 111 | if (!config->reloading && !config->validating) { |
112 | apply_output_config_to_outputs(output); | 112 | apply_output_config_to_outputs(output); |
113 | if (background) { | 113 | if (background) { |
114 | spawn_swaybg(); | 114 | if (!spawn_swaybg()) { |
115 | return cmd_results_new(CMD_FAILURE, | ||
116 | "Failed to apply background configuration"); | ||
117 | } | ||
115 | } | 118 | } |
116 | } | 119 | } |
117 | 120 | ||
diff --git a/sway/commands/output/background.c b/sway/commands/output/background.c index d691295f..55bd7671 100644 --- a/sway/commands/output/background.c +++ b/sway/commands/output/background.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <libgen.h> | 1 | #include <libgen.h> |
3 | #include <stdio.h> | 2 | #include <stdio.h> |
4 | #include <string.h> | 3 | #include <string.h> |
diff --git a/sway/commands/primary_selection.c b/sway/commands/primary_selection.c index 585b079d..9e2689c2 100644 --- a/sway/commands/primary_selection.c +++ b/sway/commands/primary_selection.c | |||
@@ -12,12 +12,14 @@ struct cmd_results *cmd_primary_selection(int argc, char **argv) { | |||
12 | 12 | ||
13 | bool primary_selection = parse_boolean(argv[0], true); | 13 | bool primary_selection = parse_boolean(argv[0], true); |
14 | 14 | ||
15 | // config->primary_selection is reset to the previous value on reload in | ||
16 | // load_main_config() | ||
15 | if (config->reloading && config->primary_selection != primary_selection) { | 17 | if (config->reloading && config->primary_selection != primary_selection) { |
16 | return cmd_results_new(CMD_FAILURE, | 18 | return cmd_results_new(CMD_FAILURE, |
17 | "primary_selection can only be enabled/disabled at launch"); | 19 | "primary_selection can only be enabled/disabled at launch"); |
18 | } | 20 | } |
19 | 21 | ||
20 | config->primary_selection = parse_boolean(argv[0], true); | 22 | config->primary_selection = primary_selection; |
21 | 23 | ||
22 | return cmd_results_new(CMD_SUCCESS, NULL); | 24 | return cmd_results_new(CMD_SUCCESS, NULL); |
23 | } | 25 | } |
diff --git a/sway/commands/reload.c b/sway/commands/reload.c index 82967ca7..6c0aac26 100644 --- a/sway/commands/reload.c +++ b/sway/commands/reload.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/seat/attach.c b/sway/commands/seat/attach.c index 00bfdab6..47d18546 100644 --- a/sway/commands/seat/attach.c +++ b/sway/commands/seat/attach.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/seat/cursor.c b/sway/commands/seat/cursor.c index 5a8a3bc8..df7c379d 100644 --- a/sway/commands/seat/cursor.c +++ b/sway/commands/seat/cursor.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <linux/input-event-codes.h> | 1 | #include <linux/input-event-codes.h> |
3 | 2 | ||
4 | #include <strings.h> | 3 | #include <strings.h> |
@@ -85,12 +84,12 @@ struct cmd_results *seat_cmd_cursor(int argc, char **argv) { | |||
85 | 84 | ||
86 | static struct cmd_results *press_or_release(struct sway_cursor *cursor, | 85 | static struct cmd_results *press_or_release(struct sway_cursor *cursor, |
87 | char *action, char *button_str) { | 86 | char *action, char *button_str) { |
88 | enum wlr_button_state state; | 87 | enum wl_pointer_button_state state; |
89 | uint32_t button; | 88 | uint32_t button; |
90 | if (strcasecmp(action, "press") == 0) { | 89 | if (strcasecmp(action, "press") == 0) { |
91 | state = WLR_BUTTON_PRESSED; | 90 | state = WL_POINTER_BUTTON_STATE_PRESSED; |
92 | } else if (strcasecmp(action, "release") == 0) { | 91 | } else if (strcasecmp(action, "release") == 0) { |
93 | state = WLR_BUTTON_RELEASED; | 92 | state = WL_POINTER_BUTTON_STATE_RELEASED; |
94 | } else { | 93 | } else { |
95 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); | 94 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
96 | } | 95 | } |
@@ -105,16 +104,16 @@ static struct cmd_results *press_or_release(struct sway_cursor *cursor, | |||
105 | } else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN | 104 | } else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN |
106 | || button == SWAY_SCROLL_LEFT || button == SWAY_SCROLL_RIGHT) { | 105 | || button == SWAY_SCROLL_LEFT || button == SWAY_SCROLL_RIGHT) { |
107 | // Dispatch axis event | 106 | // Dispatch axis event |
108 | enum wlr_axis_orientation orientation = | 107 | enum wl_pointer_axis orientation = |
109 | (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN) | 108 | (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN) |
110 | ? WLR_AXIS_ORIENTATION_VERTICAL | 109 | ? WL_POINTER_AXIS_VERTICAL_SCROLL |
111 | : WLR_AXIS_ORIENTATION_HORIZONTAL; | 110 | : WL_POINTER_AXIS_HORIZONTAL_SCROLL; |
112 | double delta = (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_LEFT) | 111 | double delta = (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_LEFT) |
113 | ? -1 : 1; | 112 | ? -1 : 1; |
114 | struct wlr_pointer_axis_event event = { | 113 | struct wlr_pointer_axis_event event = { |
115 | .pointer = NULL, | 114 | .pointer = NULL, |
116 | .time_msec = 0, | 115 | .time_msec = 0, |
117 | .source = WLR_AXIS_SOURCE_WHEEL, | 116 | .source = WL_POINTER_AXIS_SOURCE_WHEEL, |
118 | .orientation = orientation, | 117 | .orientation = orientation, |
119 | .delta = delta * 15, | 118 | .delta = delta * 15, |
120 | .delta_discrete = delta | 119 | .delta_discrete = delta |
diff --git a/sway/commands/seat/hide_cursor.c b/sway/commands/seat/hide_cursor.c index e09b82d9..f5177a47 100644 --- a/sway/commands/seat/hide_cursor.c +++ b/sway/commands/seat/hide_cursor.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/seat/idle.c b/sway/commands/seat/idle.c index 62b94db2..2974453e 100644 --- a/sway/commands/seat/idle.c +++ b/sway/commands/seat/idle.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <limits.h> | 1 | #include <limits.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include <strings.h> | 3 | #include <strings.h> |
diff --git a/sway/commands/seat/xcursor_theme.c b/sway/commands/seat/xcursor_theme.c index 202f35b9..61322a57 100644 --- a/sway/commands/seat/xcursor_theme.c +++ b/sway/commands/seat/xcursor_theme.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/set.c b/sway/commands/set.c index c539e9fc..ba384c7c 100644 --- a/sway/commands/set.c +++ b/sway/commands/set.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdio.h> | 1 | #include <stdio.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include <strings.h> | 3 | #include <strings.h> |
diff --git a/sway/commands/show_marks.c b/sway/commands/show_marks.c index fecb5ade..60cef9fa 100644 --- a/sway/commands/show_marks.c +++ b/sway/commands/show_marks.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/swap.c b/sway/commands/swap.c index d44eb006..e142eede 100644 --- a/sway/commands/swap.c +++ b/sway/commands/swap.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <strings.h> | 1 | #include <strings.h> |
3 | #include "config.h" | 2 | #include "config.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/title_format.c b/sway/commands/title_format.c index a2446b7e..0b2ea265 100644 --- a/sway/commands/title_format.c +++ b/sway/commands/title_format.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c index c3a6ac4b..4aba5bae 100644 --- a/sway/commands/unmark.c +++ b/sway/commands/unmark.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index 8536929e..37a201b4 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <ctype.h> | 1 | #include <ctype.h> |
3 | #include <limits.h> | 2 | #include <limits.h> |
4 | #include <string.h> | 3 | #include <string.h> |
diff --git a/sway/commands/xwayland.c b/sway/commands/xwayland.c index 6ca26923..584a8e3a 100644 --- a/sway/commands/xwayland.c +++ b/sway/commands/xwayland.c | |||
@@ -20,6 +20,8 @@ struct cmd_results *cmd_xwayland(int argc, char **argv) { | |||
20 | xwayland = XWAYLAND_MODE_DISABLED; | 20 | xwayland = XWAYLAND_MODE_DISABLED; |
21 | } | 21 | } |
22 | 22 | ||
23 | // config->xwayland is reset to the previous value on reload in | ||
24 | // load_main_config() | ||
23 | if (config->reloading && config->xwayland != xwayland) { | 25 | if (config->reloading && config->xwayland != xwayland) { |
24 | return cmd_results_new(CMD_FAILURE, | 26 | return cmd_results_new(CMD_FAILURE, |
25 | "xwayland can only be enabled/disabled at launch"); | 27 | "xwayland can only be enabled/disabled at launch"); |
diff --git a/sway/config.c b/sway/config.c index 4b51dc73..72fc41e7 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #undef _POSIX_C_SOURCE | ||
1 | #define _XOPEN_SOURCE 700 // for realpath | 2 | #define _XOPEN_SOURCE 700 // for realpath |
2 | #include <stdio.h> | 3 | #include <stdio.h> |
3 | #include <stdbool.h> | 4 | #include <stdbool.h> |
@@ -36,19 +37,26 @@ | |||
36 | struct sway_config *config = NULL; | 37 | struct sway_config *config = NULL; |
37 | 38 | ||
38 | static struct xkb_state *keysym_translation_state_create( | 39 | static struct xkb_state *keysym_translation_state_create( |
39 | struct xkb_rule_names rules) { | 40 | struct xkb_rule_names rules, uint32_t context_flags) { |
40 | struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_SECURE_GETENV); | 41 | struct xkb_context *context = xkb_context_new(context_flags | XKB_CONTEXT_NO_SECURE_GETENV); |
41 | struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_names( | 42 | struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_names( |
42 | context, | 43 | context, |
43 | &rules, | 44 | &rules, |
44 | XKB_KEYMAP_COMPILE_NO_FLAGS); | 45 | XKB_KEYMAP_COMPILE_NO_FLAGS); |
45 | |||
46 | xkb_context_unref(context); | 46 | xkb_context_unref(context); |
47 | if (xkb_keymap == NULL) { | ||
48 | sway_log(SWAY_ERROR, "Failed to compile keysym translation XKB keymap"); | ||
49 | return NULL; | ||
50 | } | ||
51 | |||
47 | return xkb_state_new(xkb_keymap); | 52 | return xkb_state_new(xkb_keymap); |
48 | } | 53 | } |
49 | 54 | ||
50 | static void keysym_translation_state_destroy( | 55 | static void keysym_translation_state_destroy( |
51 | struct xkb_state *state) { | 56 | struct xkb_state *state) { |
57 | if (state == NULL) { | ||
58 | return; | ||
59 | } | ||
52 | xkb_keymap_unref(xkb_state_get_keymap(state)); | 60 | xkb_keymap_unref(xkb_state_get_keymap(state)); |
53 | xkb_state_unref(state); | 61 | xkb_state_unref(state); |
54 | } | 62 | } |
@@ -336,8 +344,14 @@ static void config_defaults(struct sway_config *config) { | |||
336 | 344 | ||
337 | // The keysym to keycode translation | 345 | // The keysym to keycode translation |
338 | struct xkb_rule_names rules = {0}; | 346 | struct xkb_rule_names rules = {0}; |
339 | config->keysym_translation_state = | 347 | config->keysym_translation_state = keysym_translation_state_create(rules, 0); |
340 | keysym_translation_state_create(rules); | 348 | if (config->keysym_translation_state == NULL) { |
349 | config->keysym_translation_state = keysym_translation_state_create(rules, | ||
350 | XKB_CONTEXT_NO_ENVIRONMENT_NAMES); | ||
351 | } | ||
352 | if (config->keysym_translation_state == NULL) { | ||
353 | goto cleanup; | ||
354 | } | ||
341 | 355 | ||
342 | return; | 356 | return; |
343 | cleanup: | 357 | cleanup: |
@@ -352,13 +366,7 @@ static char *config_path(const char *prefix, const char *config_folder) { | |||
352 | if (!prefix || !prefix[0] || !config_folder || !config_folder[0]) { | 366 | if (!prefix || !prefix[0] || !config_folder || !config_folder[0]) { |
353 | return NULL; | 367 | return NULL; |
354 | } | 368 | } |
355 | 369 | return format_str("%s/%s/config", prefix, config_folder); | |
356 | const char *filename = "config"; | ||
357 | |||
358 | size_t size = 3 + strlen(prefix) + strlen(config_folder) + strlen(filename); | ||
359 | char *path = calloc(size, sizeof(char)); | ||
360 | snprintf(path, size, "%s/%s/%s", prefix, config_folder, filename); | ||
361 | return path; | ||
362 | } | 370 | } |
363 | 371 | ||
364 | static char *get_config_path(void) { | 372 | static char *get_config_path(void) { |
@@ -368,10 +376,7 @@ static char *get_config_path(void) { | |||
368 | 376 | ||
369 | const char *config_home = getenv("XDG_CONFIG_HOME"); | 377 | const char *config_home = getenv("XDG_CONFIG_HOME"); |
370 | if ((config_home == NULL || config_home[0] == '\0') && home != NULL) { | 378 | if ((config_home == NULL || config_home[0] == '\0') && home != NULL) { |
371 | size_t size_fallback = 1 + strlen(home) + strlen("/.config"); | 379 | config_home_fallback = format_str("%s/.config", home); |
372 | config_home_fallback = calloc(size_fallback, sizeof(char)); | ||
373 | if (config_home_fallback != NULL) | ||
374 | snprintf(config_home_fallback, size_fallback, "%s/.config", home); | ||
375 | config_home = config_home_fallback; | 380 | config_home = config_home_fallback; |
376 | } | 381 | } |
377 | 382 | ||
@@ -475,6 +480,11 @@ bool load_main_config(const char *file, bool is_active, bool validating) { | |||
475 | old_config->xwayland ? "enabled" : "disabled"); | 480 | old_config->xwayland ? "enabled" : "disabled"); |
476 | config->xwayland = old_config->xwayland; | 481 | config->xwayland = old_config->xwayland; |
477 | 482 | ||
483 | // primary_selection can only be enabled/disabled at launch | ||
484 | sway_log(SWAY_DEBUG, "primary_selection will remain %s", | ||
485 | old_config->primary_selection ? "enabled" : "disabled"); | ||
486 | config->primary_selection = old_config->primary_selection; | ||
487 | |||
478 | if (!config->validating) { | 488 | if (!config->validating) { |
479 | if (old_config->swaybg_client != NULL) { | 489 | if (old_config->swaybg_client != NULL) { |
480 | wl_client_destroy(old_config->swaybg_client); | 490 | wl_client_destroy(old_config->swaybg_client); |
@@ -494,56 +504,7 @@ bool load_main_config(const char *file, bool is_active, bool validating) { | |||
494 | 504 | ||
495 | config->reading = true; | 505 | config->reading = true; |
496 | 506 | ||
497 | // Read security configs | 507 | bool success = load_config(path, config, &config->swaynag_config_errors); |
498 | // TODO: Security | ||
499 | bool success = true; | ||
500 | /* | ||
501 | DIR *dir = opendir(SYSCONFDIR "/sway/security.d"); | ||
502 | if (!dir) { | ||
503 | sway_log(SWAY_ERROR, | ||
504 | "%s does not exist, sway will have no security configuration" | ||
505 | " and will probably be broken", SYSCONFDIR "/sway/security.d"); | ||
506 | } else { | ||
507 | list_t *secconfigs = create_list(); | ||
508 | char *base = SYSCONFDIR "/sway/security.d/"; | ||
509 | struct dirent *ent = readdir(dir); | ||
510 | struct stat s; | ||
511 | while (ent != NULL) { | ||
512 | char *_path = malloc(strlen(ent->d_name) + strlen(base) + 1); | ||
513 | strcpy(_path, base); | ||
514 | strcat(_path, ent->d_name); | ||
515 | lstat(_path, &s); | ||
516 | if (S_ISREG(s.st_mode) && ent->d_name[0] != '.') { | ||
517 | list_add(secconfigs, _path); | ||
518 | } | ||
519 | else { | ||
520 | free(_path); | ||
521 | } | ||
522 | ent = readdir(dir); | ||
523 | } | ||
524 | closedir(dir); | ||
525 | |||
526 | list_qsort(secconfigs, qstrcmp); | ||
527 | for (int i = 0; i < secconfigs->length; ++i) { | ||
528 | char *_path = secconfigs->items[i]; | ||
529 | if (stat(_path, &s) || s.st_uid != 0 || s.st_gid != 0 || | ||
530 | (((s.st_mode & 0777) != 0644) && | ||
531 | (s.st_mode & 0777) != 0444)) { | ||
532 | sway_log(SWAY_ERROR, | ||
533 | "Refusing to load %s - it must be owned by root " | ||
534 | "and mode 644 or 444", _path); | ||
535 | success = false; | ||
536 | } else { | ||
537 | success = success && load_config(_path, config); | ||
538 | } | ||
539 | } | ||
540 | |||
541 | list_free_items_and_destroy(secconfigs); | ||
542 | } | ||
543 | */ | ||
544 | |||
545 | success = success && load_config(path, config, | ||
546 | &config->swaynag_config_errors); | ||
547 | 508 | ||
548 | if (validating) { | 509 | if (validating) { |
549 | free_config(config); | 510 | free_config(config); |
@@ -1037,8 +998,12 @@ void translate_keysyms(struct input_config *input_config) { | |||
1037 | 998 | ||
1038 | struct xkb_rule_names rules = {0}; | 999 | struct xkb_rule_names rules = {0}; |
1039 | input_config_fill_rule_names(input_config, &rules); | 1000 | input_config_fill_rule_names(input_config, &rules); |
1040 | config->keysym_translation_state = | 1001 | config->keysym_translation_state = keysym_translation_state_create(rules, 0); |
1041 | keysym_translation_state_create(rules); | 1002 | if (config->keysym_translation_state == NULL) { |
1003 | sway_log(SWAY_ERROR, "Failed to create keysym translation XKB state " | ||
1004 | "for device '%s'", input_config->identifier); | ||
1005 | return; | ||
1006 | } | ||
1042 | 1007 | ||
1043 | for (int i = 0; i < config->modes->length; ++i) { | 1008 | for (int i = 0; i < config->modes->length; ++i) { |
1044 | struct sway_mode *mode = config->modes->items[i]; | 1009 | struct sway_mode *mode = config->modes->items[i]; |
diff --git a/sway/config/bar.c b/sway/config/bar.c index a8389244..908b2865 100644 --- a/sway/config/bar.c +++ b/sway/config/bar.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <signal.h> | 1 | #include <signal.h> |
3 | #include <stdbool.h> | 2 | #include <stdbool.h> |
4 | #include <stdio.h> | 3 | #include <stdio.h> |
diff --git a/sway/config/input.c b/sway/config/input.c index 44c2be28..de3b21ed 100644 --- a/sway/config/input.c +++ b/sway/config/input.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdlib.h> | 1 | #include <stdlib.h> |
3 | #include <limits.h> | 2 | #include <limits.h> |
4 | #include <float.h> | 3 | #include <float.h> |
diff --git a/sway/config/output.c b/sway/config/output.c index 1a5215fe..1b2332e9 100644 --- a/sway/config/output.c +++ b/sway/config/output.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <drm_fourcc.h> | 2 | #include <drm_fourcc.h> |
4 | #include <stdbool.h> | 3 | #include <stdbool.h> |
@@ -511,9 +510,6 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { | |||
511 | 510 | ||
512 | struct wlr_output *wlr_output = output->wlr_output; | 511 | struct wlr_output *wlr_output = output->wlr_output; |
513 | 512 | ||
514 | // Flag to prevent the output mode event handler from calling us | ||
515 | output->enabling = (!oc || oc->enabled); | ||
516 | |||
517 | struct wlr_output_state pending = {0}; | 513 | struct wlr_output_state pending = {0}; |
518 | queue_output_config(oc, output, &pending); | 514 | queue_output_config(oc, output, &pending); |
519 | 515 | ||
@@ -523,12 +519,9 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { | |||
523 | // Leave the output disabled for now and try again when the output gets | 519 | // Leave the output disabled for now and try again when the output gets |
524 | // the mode we asked for. | 520 | // the mode we asked for. |
525 | sway_log(SWAY_ERROR, "Failed to commit output %s", wlr_output->name); | 521 | sway_log(SWAY_ERROR, "Failed to commit output %s", wlr_output->name); |
526 | output->enabling = false; | ||
527 | return false; | 522 | return false; |
528 | } | 523 | } |
529 | 524 | ||
530 | output->enabling = false; | ||
531 | |||
532 | if (oc && !oc->enabled) { | 525 | if (oc && !oc->enabled) { |
533 | sway_log(SWAY_DEBUG, "Disabling output %s", oc->name); | 526 | sway_log(SWAY_DEBUG, "Disabling output %s", oc->name); |
534 | if (output->enabled) { | 527 | if (output->enabled) { |
@@ -822,7 +815,9 @@ static bool _spawn_swaybg(char **command) { | |||
822 | setenv("WAYLAND_SOCKET", wayland_socket_str, true); | 815 | setenv("WAYLAND_SOCKET", wayland_socket_str, true); |
823 | 816 | ||
824 | execvp(command[0], command); | 817 | execvp(command[0], command); |
825 | sway_log_errno(SWAY_ERROR, "execvp failed"); | 818 | sway_log_errno(SWAY_ERROR, "failed to execute '%s' " |
819 | "(background configuration probably not applied)", | ||
820 | command[0]); | ||
826 | _exit(EXIT_FAILURE); | 821 | _exit(EXIT_FAILURE); |
827 | } | 822 | } |
828 | _exit(EXIT_SUCCESS); | 823 | _exit(EXIT_SUCCESS); |
@@ -832,12 +827,13 @@ static bool _spawn_swaybg(char **command) { | |||
832 | sway_log_errno(SWAY_ERROR, "close failed"); | 827 | sway_log_errno(SWAY_ERROR, "close failed"); |
833 | return false; | 828 | return false; |
834 | } | 829 | } |
835 | if (waitpid(pid, NULL, 0) < 0) { | 830 | int fork_status = 0; |
831 | if (waitpid(pid, &fork_status, 0) < 0) { | ||
836 | sway_log_errno(SWAY_ERROR, "waitpid failed"); | 832 | sway_log_errno(SWAY_ERROR, "waitpid failed"); |
837 | return false; | 833 | return false; |
838 | } | 834 | } |
839 | 835 | ||
840 | return true; | 836 | return WIFEXITED(fork_status) && WEXITSTATUS(fork_status) == EXIT_SUCCESS; |
841 | } | 837 | } |
842 | 838 | ||
843 | bool spawn_swaybg(void) { | 839 | bool spawn_swaybg(void) { |
diff --git a/sway/config/seat.c b/sway/config/seat.c index 6d5d91ae..f2326189 100644 --- a/sway/config/seat.c +++ b/sway/config/seat.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <limits.h> | 1 | #include <limits.h> |
3 | #include <stdlib.h> | 2 | #include <stdlib.h> |
4 | #include <string.h> | 3 | #include <string.h> |
diff --git a/sway/criteria.c b/sway/criteria.c index 78ea8b8a..e16b4fa8 100644 --- a/sway/criteria.c +++ b/sway/criteria.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdlib.h> | 1 | #include <stdlib.h> |
3 | #include <stdio.h> | 2 | #include <stdio.h> |
4 | #include <stdbool.h> | 3 | #include <stdbool.h> |
diff --git a/sway/desktop/launcher.c b/sway/desktop/launcher.c index 00a7e38a..28043d19 100644 --- a/sway/desktop/launcher.c +++ b/sway/desktop/launcher.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdlib.h> | 1 | #include <stdlib.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include <wlr/types/wlr_xdg_activation_v1.h> | 3 | #include <wlr/types/wlr_xdg_activation_v1.h> |
@@ -67,6 +66,9 @@ void launcher_ctx_destroy(struct launcher_ctx *ctx) { | |||
67 | } | 66 | } |
68 | wl_list_remove(&ctx->node_destroy.link); | 67 | wl_list_remove(&ctx->node_destroy.link); |
69 | wl_list_remove(&ctx->token_destroy.link); | 68 | wl_list_remove(&ctx->token_destroy.link); |
69 | if (ctx->seat) { | ||
70 | wl_list_remove(&ctx->seat_destroy.link); | ||
71 | } | ||
70 | wl_list_remove(&ctx->link); | 72 | wl_list_remove(&ctx->link); |
71 | wlr_xdg_activation_token_v1_destroy(ctx->token); | 73 | wlr_xdg_activation_token_v1_destroy(ctx->token); |
72 | free(ctx->fallback_name); | 74 | free(ctx->fallback_name); |
@@ -213,6 +215,8 @@ struct launcher_ctx *launcher_ctx_create(struct wlr_xdg_activation_token_v1 *tok | |||
213 | ctx->fallback_name = strdup(fallback_name); | 215 | ctx->fallback_name = strdup(fallback_name); |
214 | ctx->token = token; | 216 | ctx->token = token; |
215 | ctx->node = node; | 217 | ctx->node = node; |
218 | // Having surface set means that the focus check in wlroots has passed | ||
219 | ctx->had_focused_surface = token->surface != NULL; | ||
216 | 220 | ||
217 | ctx->node_destroy.notify = ctx_handle_node_destroy; | 221 | ctx->node_destroy.notify = ctx_handle_node_destroy; |
218 | wl_signal_add(&ctx->node->events.destroy, &ctx->node_destroy); | 222 | wl_signal_add(&ctx->node->events.destroy, &ctx->node_destroy); |
@@ -227,6 +231,12 @@ struct launcher_ctx *launcher_ctx_create(struct wlr_xdg_activation_token_v1 *tok | |||
227 | return ctx; | 231 | return ctx; |
228 | } | 232 | } |
229 | 233 | ||
234 | static void launch_ctx_handle_seat_destroy(struct wl_listener *listener, void *data) { | ||
235 | struct launcher_ctx *ctx = wl_container_of(listener, ctx, seat_destroy); | ||
236 | ctx->seat = NULL; | ||
237 | wl_list_remove(&ctx->seat_destroy.link); | ||
238 | } | ||
239 | |||
230 | // Creates a context with a new token for the internal launcher | 240 | // Creates a context with a new token for the internal launcher |
231 | struct launcher_ctx *launcher_ctx_create_internal(void) { | 241 | struct launcher_ctx *launcher_ctx_create_internal(void) { |
232 | struct sway_seat *seat = input_manager_current_seat(); | 242 | struct sway_seat *seat = input_manager_current_seat(); |
@@ -238,13 +248,15 @@ struct launcher_ctx *launcher_ctx_create_internal(void) { | |||
238 | 248 | ||
239 | struct wlr_xdg_activation_token_v1 *token = | 249 | struct wlr_xdg_activation_token_v1 *token = |
240 | wlr_xdg_activation_token_v1_create(server.xdg_activation_v1); | 250 | wlr_xdg_activation_token_v1_create(server.xdg_activation_v1); |
241 | token->seat = seat->wlr_seat; | ||
242 | 251 | ||
243 | struct launcher_ctx *ctx = launcher_ctx_create(token, &ws->node); | 252 | struct launcher_ctx *ctx = launcher_ctx_create(token, &ws->node); |
244 | if (!ctx) { | 253 | if (!ctx) { |
245 | wlr_xdg_activation_token_v1_destroy(token); | 254 | wlr_xdg_activation_token_v1_destroy(token); |
246 | return NULL; | 255 | return NULL; |
247 | } | 256 | } |
257 | ctx->seat = seat; | ||
258 | ctx->seat_destroy.notify = launch_ctx_handle_seat_destroy; | ||
259 | wl_signal_add(&seat->wlr_seat->events.destroy, &ctx->seat_destroy); | ||
248 | 260 | ||
249 | return ctx; | 261 | return ctx; |
250 | } | 262 | } |
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index c71abce7..4b2584b6 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c | |||
@@ -4,7 +4,9 @@ | |||
4 | #include <wayland-server-core.h> | 4 | #include <wayland-server-core.h> |
5 | #include <wlr/types/wlr_layer_shell_v1.h> | 5 | #include <wlr/types/wlr_layer_shell_v1.h> |
6 | #include <wlr/types/wlr_output.h> | 6 | #include <wlr/types/wlr_output.h> |
7 | #include <wlr/types/wlr_scene.h> | ||
7 | #include <wlr/types/wlr_subcompositor.h> | 8 | #include <wlr/types/wlr_subcompositor.h> |
9 | #include <wlr/types/wlr_xdg_shell.h> | ||
8 | #include "log.h" | 10 | #include "log.h" |
9 | #include "sway/scene_descriptor.h" | 11 | #include "sway/scene_descriptor.h" |
10 | #include "sway/desktop/transaction.h" | 12 | #include "sway/desktop/transaction.h" |
@@ -16,7 +18,6 @@ | |||
16 | #include "sway/server.h" | 18 | #include "sway/server.h" |
17 | #include "sway/tree/arrange.h" | 19 | #include "sway/tree/arrange.h" |
18 | #include "sway/tree/workspace.h" | 20 | #include "sway/tree/workspace.h" |
19 | #include <wlr/types/wlr_scene.h> | ||
20 | 21 | ||
21 | struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface( | 22 | struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface( |
22 | struct wlr_surface *surface) { | 23 | struct wlr_surface *surface) { |
@@ -85,6 +86,8 @@ void arrange_layers(struct sway_output *output) { | |||
85 | sway_log(SWAY_DEBUG, "Usable area changed, rearranging output"); | 86 | sway_log(SWAY_DEBUG, "Usable area changed, rearranging output"); |
86 | output->usable_area = usable_area; | 87 | output->usable_area = usable_area; |
87 | arrange_output(output); | 88 | arrange_output(output); |
89 | } else { | ||
90 | arrange_popups(root->layers.popup); | ||
88 | } | 91 | } |
89 | } | 92 | } |
90 | 93 | ||
@@ -120,10 +123,21 @@ static struct sway_layer_surface *sway_layer_surface_create( | |||
120 | return NULL; | 123 | return NULL; |
121 | } | 124 | } |
122 | 125 | ||
126 | surface->desc.relative = &scene->tree->node; | ||
127 | |||
128 | if (!scene_descriptor_assign(&popups->node, | ||
129 | SWAY_SCENE_DESC_POPUP, &surface->desc)) { | ||
130 | sway_log(SWAY_ERROR, "Failed to allocate a popup scene descriptor"); | ||
131 | wlr_scene_node_destroy(&popups->node); | ||
132 | free(surface); | ||
133 | return NULL; | ||
134 | } | ||
135 | |||
123 | surface->tree = scene->tree; | 136 | surface->tree = scene->tree; |
124 | surface->scene = scene; | 137 | surface->scene = scene; |
125 | surface->layer_surface = scene->layer_surface; | 138 | surface->layer_surface = scene->layer_surface; |
126 | surface->popups = popups; | 139 | surface->popups = popups; |
140 | surface->layer_surface->data = surface; | ||
127 | 141 | ||
128 | return surface; | 142 | return surface; |
129 | } | 143 | } |
@@ -197,6 +211,8 @@ static void handle_node_destroy(struct wl_listener *listener, void *data) { | |||
197 | wl_list_remove(&layer->node_destroy.link); | 211 | wl_list_remove(&layer->node_destroy.link); |
198 | wl_list_remove(&layer->output_destroy.link); | 212 | wl_list_remove(&layer->output_destroy.link); |
199 | 213 | ||
214 | layer->layer_surface->data = NULL; | ||
215 | |||
200 | free(layer); | 216 | free(layer); |
201 | } | 217 | } |
202 | 218 | ||
@@ -222,10 +238,6 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { | |||
222 | arrange_layers(surface->output); | 238 | arrange_layers(surface->output); |
223 | transaction_commit_dirty(); | 239 | transaction_commit_dirty(); |
224 | } | 240 | } |
225 | |||
226 | int lx, ly; | ||
227 | wlr_scene_node_coords(&surface->scene->tree->node, &lx, &ly); | ||
228 | wlr_scene_node_set_position(&surface->popups->node, lx, ly); | ||
229 | } | 241 | } |
230 | 242 | ||
231 | static void handle_map(struct wl_listener *listener, void *data) { | 243 | static void handle_map(struct wl_listener *listener, void *data) { |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 9c4baafd..b8f2d32d 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <stdlib.h> | 2 | #include <stdlib.h> |
4 | #include <strings.h> | 3 | #include <strings.h> |
@@ -12,6 +11,8 @@ | |||
12 | #include <wlr/types/wlr_gamma_control_v1.h> | 11 | #include <wlr/types/wlr_gamma_control_v1.h> |
13 | #include <wlr/types/wlr_matrix.h> | 12 | #include <wlr/types/wlr_matrix.h> |
14 | #include <wlr/types/wlr_output_layout.h> | 13 | #include <wlr/types/wlr_output_layout.h> |
14 | #include <wlr/types/wlr_output_management_v1.h> | ||
15 | #include <wlr/types/wlr_output_power_management_v1.h> | ||
15 | #include <wlr/types/wlr_output.h> | 16 | #include <wlr/types/wlr_output.h> |
16 | #include <wlr/types/wlr_presentation_time.h> | 17 | #include <wlr/types/wlr_presentation_time.h> |
17 | #include <wlr/types/wlr_compositor.h> | 18 | #include <wlr/types/wlr_compositor.h> |
@@ -182,7 +183,15 @@ static void send_frame_done_iterator(struct wlr_scene_buffer *buffer, | |||
182 | } | 183 | } |
183 | } | 184 | } |
184 | 185 | ||
185 | static enum wlr_scale_filter_mode get_scale_filter(struct sway_output *output) { | 186 | static enum wlr_scale_filter_mode get_scale_filter(struct sway_output *output, |
187 | struct wlr_scene_buffer *buffer) { | ||
188 | // if we are scaling down, we should always choose linear | ||
189 | if (buffer->dst_width > 0 && buffer->dst_height > 0 && ( | ||
190 | buffer->dst_width < buffer->buffer_width || | ||
191 | buffer->dst_height < buffer->buffer_height)) { | ||
192 | return WLR_SCALE_FILTER_BILINEAR; | ||
193 | } | ||
194 | |||
186 | switch (output->scale_filter) { | 195 | switch (output->scale_filter) { |
187 | case SCALE_FILTER_LINEAR: | 196 | case SCALE_FILTER_LINEAR: |
188 | return WLR_SCALE_FILTER_BILINEAR; | 197 | return WLR_SCALE_FILTER_BILINEAR; |
@@ -211,7 +220,7 @@ static void output_configure_scene(struct sway_output *output, | |||
211 | // hack: don't call the scene setter because that will damage all outputs | 220 | // hack: don't call the scene setter because that will damage all outputs |
212 | // We don't want to damage outputs that aren't our current output that | 221 | // We don't want to damage outputs that aren't our current output that |
213 | // we're configuring | 222 | // we're configuring |
214 | buffer->filter_mode = get_scale_filter(output); | 223 | buffer->filter_mode = get_scale_filter(output, buffer); |
215 | 224 | ||
216 | wlr_scene_buffer_set_opacity(buffer, opacity); | 225 | wlr_scene_buffer_set_opacity(buffer, opacity); |
217 | } else if (node->type == WLR_SCENE_NODE_TREE) { | 226 | } else if (node->type == WLR_SCENE_NODE_TREE) { |
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index acc3e3f9..042141ab 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdbool.h> | 1 | #include <stdbool.h> |
3 | #include <stdlib.h> | 2 | #include <stdlib.h> |
4 | #include <string.h> | 3 | #include <string.h> |
@@ -606,21 +605,15 @@ static void arrange_output(struct sway_output *output, int width, int height) { | |||
606 | } | 605 | } |
607 | } | 606 | } |
608 | 607 | ||
609 | static void arrange_popup(struct wlr_scene_tree *popup) { | 608 | void arrange_popups(struct wlr_scene_tree *popups) { |
610 | struct wlr_scene_node *node; | 609 | struct wlr_scene_node *node; |
611 | wl_list_for_each(node, &popup->children, link) { | 610 | wl_list_for_each(node, &popups->children, link) { |
612 | struct sway_xdg_popup *popup = scene_descriptor_try_get(node, | 611 | struct sway_popup_desc *popup = scene_descriptor_try_get(node, |
613 | SWAY_SCENE_DESC_POPUP); | 612 | SWAY_SCENE_DESC_POPUP); |
614 | 613 | ||
615 | // the popup layer may have popups from layer_shell surfaces, in this | 614 | int lx, ly; |
616 | // case those don't have a scene descriptor, so lets skip those here. | 615 | wlr_scene_node_coords(popup->relative, &lx, &ly); |
617 | if (popup) { | 616 | wlr_scene_node_set_position(node, lx, ly); |
618 | struct wlr_scene_tree *tree = popup->view->content_tree; | ||
619 | |||
620 | int lx, ly; | ||
621 | wlr_scene_node_coords(&tree->node, &lx, &ly); | ||
622 | wlr_scene_node_set_position(&popup->scene_tree->node, lx, ly); | ||
623 | } | ||
624 | } | 617 | } |
625 | } | 618 | } |
626 | 619 | ||
@@ -679,7 +672,7 @@ static void arrange_root(struct sway_root *root) { | |||
679 | } | 672 | } |
680 | } | 673 | } |
681 | 674 | ||
682 | arrange_popup(root->layers.popup); | 675 | arrange_popups(root->layers.popup); |
683 | } | 676 | } |
684 | 677 | ||
685 | /** | 678 | /** |
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 7cdd97c8..7c417891 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 199309L | ||
2 | #include <float.h> | 1 | #include <float.h> |
3 | #include <stdbool.h> | 2 | #include <stdbool.h> |
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
@@ -36,6 +35,7 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) { | |||
36 | wl_list_remove(&popup->new_popup.link); | 35 | wl_list_remove(&popup->new_popup.link); |
37 | wl_list_remove(&popup->destroy.link); | 36 | wl_list_remove(&popup->destroy.link); |
38 | wl_list_remove(&popup->surface_commit.link); | 37 | wl_list_remove(&popup->surface_commit.link); |
38 | wl_list_remove(&popup->reposition.link); | ||
39 | wlr_scene_node_destroy(&popup->scene_tree->node); | 39 | wlr_scene_node_destroy(&popup->scene_tree->node); |
40 | free(popup); | 40 | free(popup); |
41 | } | 41 | } |
@@ -71,6 +71,11 @@ static void popup_handle_surface_commit(struct wl_listener *listener, void *data | |||
71 | } | 71 | } |
72 | } | 72 | } |
73 | 73 | ||
74 | static void popup_handle_reposition(struct wl_listener *listener, void *data) { | ||
75 | struct sway_xdg_popup *popup = wl_container_of(listener, popup, reposition); | ||
76 | popup_unconstrain(popup); | ||
77 | } | ||
78 | |||
74 | static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup, | 79 | static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup, |
75 | struct sway_view *view, struct wlr_scene_tree *parent) { | 80 | struct sway_view *view, struct wlr_scene_tree *parent) { |
76 | struct wlr_xdg_surface *xdg_surface = wlr_popup->base; | 81 | struct wlr_xdg_surface *xdg_surface = wlr_popup->base; |
@@ -97,8 +102,11 @@ static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup, | |||
97 | return NULL; | 102 | return NULL; |
98 | } | 103 | } |
99 | 104 | ||
105 | popup->desc.relative = &view->content_tree->node; | ||
106 | popup->desc.view = view; | ||
107 | |||
100 | if (!scene_descriptor_assign(&popup->scene_tree->node, | 108 | if (!scene_descriptor_assign(&popup->scene_tree->node, |
101 | SWAY_SCENE_DESC_POPUP, popup)) { | 109 | SWAY_SCENE_DESC_POPUP, &popup->desc)) { |
102 | sway_log(SWAY_ERROR, "Failed to allocate a popup scene descriptor"); | 110 | sway_log(SWAY_ERROR, "Failed to allocate a popup scene descriptor"); |
103 | wlr_scene_node_destroy(&popup->scene_tree->node); | 111 | wlr_scene_node_destroy(&popup->scene_tree->node); |
104 | free(popup); | 112 | free(popup); |
@@ -114,6 +122,8 @@ static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup, | |||
114 | popup->surface_commit.notify = popup_handle_surface_commit; | 122 | popup->surface_commit.notify = popup_handle_surface_commit; |
115 | wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); | 123 | wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); |
116 | popup->new_popup.notify = popup_handle_new_popup; | 124 | popup->new_popup.notify = popup_handle_new_popup; |
125 | wl_signal_add(&wlr_popup->events.reposition, &popup->reposition); | ||
126 | popup->reposition.notify = popup_handle_reposition; | ||
117 | wl_signal_add(&wlr_popup->events.destroy, &popup->destroy); | 127 | wl_signal_add(&wlr_popup->events.destroy, &popup->destroy); |
118 | popup->destroy.notify = popup_handle_destroy; | 128 | popup->destroy.notify = popup_handle_destroy; |
119 | 129 | ||
@@ -279,6 +289,7 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
279 | } | 289 | } |
280 | // XXX: https://github.com/swaywm/sway/issues/2176 | 290 | // XXX: https://github.com/swaywm/sway/issues/2176 |
281 | wlr_xdg_surface_schedule_configure(xdg_surface); | 291 | wlr_xdg_surface_schedule_configure(xdg_surface); |
292 | // TODO: wlr_xdg_toplevel_set_bounds() | ||
282 | return; | 293 | return; |
283 | } | 294 | } |
284 | 295 | ||
@@ -337,6 +348,7 @@ static void handle_set_app_id(struct wl_listener *listener, void *data) { | |||
337 | struct sway_xdg_shell_view *xdg_shell_view = | 348 | struct sway_xdg_shell_view *xdg_shell_view = |
338 | wl_container_of(listener, xdg_shell_view, set_app_id); | 349 | wl_container_of(listener, xdg_shell_view, set_app_id); |
339 | struct sway_view *view = &xdg_shell_view->view; | 350 | struct sway_view *view = &xdg_shell_view->view; |
351 | view_update_app_id(view); | ||
340 | view_execute_criteria(view); | 352 | view_execute_criteria(view); |
341 | } | 353 | } |
342 | 354 | ||
@@ -563,4 +575,7 @@ void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data) { | |||
563 | wlr_scene_xdg_surface_create(xdg_shell_view->view.content_tree, xdg_toplevel->base); | 575 | wlr_scene_xdg_surface_create(xdg_shell_view->view.content_tree, xdg_toplevel->base); |
564 | 576 | ||
565 | xdg_toplevel->base->data = xdg_shell_view; | 577 | xdg_toplevel->base->data = xdg_shell_view; |
578 | |||
579 | wlr_xdg_toplevel_set_wm_capabilities(xdg_toplevel, | ||
580 | XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); | ||
566 | } | 581 | } |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 9f3f4d5f..270cf08f 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 199309L | ||
2 | #include <float.h> | 1 | #include <float.h> |
3 | #include <stdbool.h> | 2 | #include <stdbool.h> |
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 404c1eed..3d04826c 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <math.h> | 2 | #include <math.h> |
4 | #include <libevdev/libevdev.h> | 3 | #include <libevdev/libevdev.h> |
@@ -9,6 +8,7 @@ | |||
9 | #include <wlr/types/wlr_cursor.h> | 8 | #include <wlr/types/wlr_cursor.h> |
10 | #include <wlr/types/wlr_cursor_shape_v1.h> | 9 | #include <wlr/types/wlr_cursor_shape_v1.h> |
11 | #include <wlr/types/wlr_pointer.h> | 10 | #include <wlr/types/wlr_pointer.h> |
11 | #include <wlr/types/wlr_relative_pointer_v1.h> | ||
12 | #include <wlr/types/wlr_touch.h> | 12 | #include <wlr/types/wlr_touch.h> |
13 | #include <wlr/types/wlr_tablet_v2.h> | 13 | #include <wlr/types/wlr_tablet_v2.h> |
14 | #include <wlr/types/wlr_tablet_pad.h> | 14 | #include <wlr/types/wlr_tablet_pad.h> |
@@ -90,9 +90,9 @@ struct sway_node *node_at_coords( | |||
90 | } | 90 | } |
91 | 91 | ||
92 | if (!con) { | 92 | if (!con) { |
93 | struct sway_xdg_popup *popup = | 93 | struct sway_popup_desc *popup = |
94 | scene_descriptor_try_get(current, SWAY_SCENE_DESC_POPUP); | 94 | scene_descriptor_try_get(current, SWAY_SCENE_DESC_POPUP); |
95 | if (popup) { | 95 | if (popup && popup->view) { |
96 | con = popup->view->container; | 96 | con = popup->view->container; |
97 | } | 97 | } |
98 | } | 98 | } |
@@ -243,7 +243,7 @@ static enum sway_input_idle_source idle_source_from_device( | |||
243 | return IDLE_SOURCE_POINTER; | 243 | return IDLE_SOURCE_POINTER; |
244 | case WLR_INPUT_DEVICE_TOUCH: | 244 | case WLR_INPUT_DEVICE_TOUCH: |
245 | return IDLE_SOURCE_TOUCH; | 245 | return IDLE_SOURCE_TOUCH; |
246 | case WLR_INPUT_DEVICE_TABLET_TOOL: | 246 | case WLR_INPUT_DEVICE_TABLET: |
247 | return IDLE_SOURCE_TABLET_TOOL; | 247 | return IDLE_SOURCE_TABLET_TOOL; |
248 | case WLR_INPUT_DEVICE_TABLET_PAD: | 248 | case WLR_INPUT_DEVICE_TABLET_PAD: |
249 | return IDLE_SOURCE_TABLET_PAD; | 249 | return IDLE_SOURCE_TABLET_PAD; |
@@ -356,7 +356,7 @@ static void handle_pointer_motion_absolute( | |||
356 | 356 | ||
357 | void dispatch_cursor_button(struct sway_cursor *cursor, | 357 | void dispatch_cursor_button(struct sway_cursor *cursor, |
358 | struct wlr_input_device *device, uint32_t time_msec, uint32_t button, | 358 | struct wlr_input_device *device, uint32_t time_msec, uint32_t button, |
359 | enum wlr_button_state state) { | 359 | enum wl_pointer_button_state state) { |
360 | if (time_msec == 0) { | 360 | if (time_msec == 0) { |
361 | time_msec = get_current_time_msec(); | 361 | time_msec = get_current_time_msec(); |
362 | } | 362 | } |
@@ -368,7 +368,7 @@ static void handle_pointer_button(struct wl_listener *listener, void *data) { | |||
368 | struct sway_cursor *cursor = wl_container_of(listener, cursor, button); | 368 | struct sway_cursor *cursor = wl_container_of(listener, cursor, button); |
369 | struct wlr_pointer_button_event *event = data; | 369 | struct wlr_pointer_button_event *event = data; |
370 | 370 | ||
371 | if (event->state == WLR_BUTTON_PRESSED) { | 371 | if (event->state == WL_POINTER_BUTTON_STATE_PRESSED) { |
372 | cursor->pressed_button_count++; | 372 | cursor->pressed_button_count++; |
373 | } else { | 373 | } else { |
374 | if (cursor->pressed_button_count > 0) { | 374 | if (cursor->pressed_button_count > 0) { |
@@ -430,7 +430,7 @@ static void handle_touch_up(struct wl_listener *listener, void *data) { | |||
430 | if (cursor->pointer_touch_id == cursor->seat->touch_id) { | 430 | if (cursor->pointer_touch_id == cursor->seat->touch_id) { |
431 | cursor->pointer_touch_up = true; | 431 | cursor->pointer_touch_up = true; |
432 | dispatch_cursor_button(cursor, &event->touch->base, | 432 | dispatch_cursor_button(cursor, &event->touch->base, |
433 | event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED); | 433 | event->time_msec, BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); |
434 | } | 434 | } |
435 | } else { | 435 | } else { |
436 | seatop_touch_up(seat, event); | 436 | seatop_touch_up(seat, event); |
@@ -448,7 +448,7 @@ static void handle_touch_cancel(struct wl_listener *listener, void *data) { | |||
448 | if (cursor->pointer_touch_id == cursor->seat->touch_id) { | 448 | if (cursor->pointer_touch_id == cursor->seat->touch_id) { |
449 | cursor->pointer_touch_up = true; | 449 | cursor->pointer_touch_up = true; |
450 | dispatch_cursor_button(cursor, &event->touch->base, | 450 | dispatch_cursor_button(cursor, &event->touch->base, |
451 | event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED); | 451 | event->time_msec, BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); |
452 | } | 452 | } |
453 | } else { | 453 | } else { |
454 | seatop_touch_cancel(seat, event); | 454 | seatop_touch_cancel(seat, event); |
@@ -518,7 +518,7 @@ static void apply_mapping_from_region(struct wlr_input_device *device, | |||
518 | double x1 = region->x1, x2 = region->x2; | 518 | double x1 = region->x1, x2 = region->x2; |
519 | double y1 = region->y1, y2 = region->y2; | 519 | double y1 = region->y1, y2 = region->y2; |
520 | 520 | ||
521 | if (region->mm && device->type == WLR_INPUT_DEVICE_TABLET_TOOL) { | 521 | if (region->mm && device->type == WLR_INPUT_DEVICE_TABLET) { |
522 | struct wlr_tablet *tablet = wlr_tablet_from_input_device(device); | 522 | struct wlr_tablet *tablet = wlr_tablet_from_input_device(device); |
523 | if (tablet->width_mm == 0 || tablet->height_mm == 0) { | 523 | if (tablet->width_mm == 0 || tablet->height_mm == 0) { |
524 | return; | 524 | return; |
@@ -661,7 +661,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) { | |||
661 | event->state == WLR_TABLET_TOOL_TIP_UP) { | 661 | event->state == WLR_TABLET_TOOL_TIP_UP) { |
662 | cursor->simulating_pointer_from_tool_tip = false; | 662 | cursor->simulating_pointer_from_tool_tip = false; |
663 | dispatch_cursor_button(cursor, &event->tablet->base, event->time_msec, | 663 | dispatch_cursor_button(cursor, &event->tablet->base, event->time_msec, |
664 | BTN_LEFT, WLR_BUTTON_RELEASED); | 664 | BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); |
665 | wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); | 665 | wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); |
666 | } else if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) { | 666 | } else if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) { |
667 | // If we started holding the tool tip down on a surface that accepts | 667 | // If we started holding the tool tip down on a surface that accepts |
@@ -673,7 +673,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) { | |||
673 | } else { | 673 | } else { |
674 | cursor->simulating_pointer_from_tool_tip = true; | 674 | cursor->simulating_pointer_from_tool_tip = true; |
675 | dispatch_cursor_button(cursor, &event->tablet->base, | 675 | dispatch_cursor_button(cursor, &event->tablet->base, |
676 | event->time_msec, BTN_LEFT, WLR_BUTTON_PRESSED); | 676 | event->time_msec, BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); |
677 | wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); | 677 | wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); |
678 | } | 678 | } |
679 | } else { | 679 | } else { |
@@ -776,13 +776,13 @@ static void handle_tool_button(struct wl_listener *listener, void *data) { | |||
776 | case WLR_BUTTON_PRESSED: | 776 | case WLR_BUTTON_PRESSED: |
777 | if (cursor->tool_buttons == 0) { | 777 | if (cursor->tool_buttons == 0) { |
778 | dispatch_cursor_button(cursor, &event->tablet->base, | 778 | dispatch_cursor_button(cursor, &event->tablet->base, |
779 | event->time_msec, BTN_RIGHT, event->state); | 779 | event->time_msec, BTN_RIGHT, WL_POINTER_BUTTON_STATE_PRESSED); |
780 | } | 780 | } |
781 | break; | 781 | break; |
782 | case WLR_BUTTON_RELEASED: | 782 | case WLR_BUTTON_RELEASED: |
783 | if (cursor->tool_buttons <= 1) { | 783 | if (cursor->tool_buttons <= 1) { |
784 | dispatch_cursor_button(cursor, &event->tablet->base, | 784 | dispatch_cursor_button(cursor, &event->tablet->base, |
785 | event->time_msec, BTN_RIGHT, event->state); | 785 | event->time_msec, BTN_RIGHT, WL_POINTER_BUTTON_STATE_RELEASED); |
786 | } | 786 | } |
787 | break; | 787 | break; |
788 | } | 788 | } |
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index c1bbdde0..248ca34e 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c | |||
@@ -1,9 +1,10 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <ctype.h> | 1 | #include <ctype.h> |
3 | #include <stdio.h> | 2 | #include <stdio.h> |
4 | #include <string.h> | 3 | #include <string.h> |
5 | #include <math.h> | 4 | #include <math.h> |
5 | #include <assert.h> | ||
6 | #include <wlr/config.h> | 6 | #include <wlr/config.h> |
7 | #include <wlr/backend/libinput.h> | ||
7 | #include <wlr/types/wlr_cursor.h> | 8 | #include <wlr/types/wlr_cursor.h> |
8 | #include <wlr/types/wlr_keyboard_group.h> | 9 | #include <wlr/types/wlr_keyboard_group.h> |
9 | #include <wlr/types/wlr_virtual_keyboard_v1.h> | 10 | #include <wlr/types/wlr_virtual_keyboard_v1.h> |
@@ -66,8 +67,15 @@ struct sway_seat *input_manager_sway_seat_from_wlr_seat(struct wlr_seat *wlr_sea | |||
66 | } | 67 | } |
67 | 68 | ||
68 | char *input_device_get_identifier(struct wlr_input_device *device) { | 69 | char *input_device_get_identifier(struct wlr_input_device *device) { |
69 | int vendor = device->vendor; | 70 | int vendor = 0, product = 0; |
70 | int product = device->product; | 71 | #if WLR_HAS_LIBINPUT_BACKEND |
72 | if (wlr_input_device_is_libinput(device)) { | ||
73 | struct libinput_device *libinput_dev = wlr_libinput_get_device_handle(device); | ||
74 | vendor = libinput_device_get_id_vendor(libinput_dev); | ||
75 | product = libinput_device_get_id_product(libinput_dev); | ||
76 | } | ||
77 | #endif | ||
78 | |||
71 | char *name = strdup(device->name ? device->name : ""); | 79 | char *name = strdup(device->name ? device->name : ""); |
72 | strip_whitespace(name); | 80 | strip_whitespace(name); |
73 | 81 | ||
@@ -112,7 +120,7 @@ const char *input_device_get_type(struct sway_input_device *device) { | |||
112 | return "keyboard"; | 120 | return "keyboard"; |
113 | case WLR_INPUT_DEVICE_TOUCH: | 121 | case WLR_INPUT_DEVICE_TOUCH: |
114 | return "touch"; | 122 | return "touch"; |
115 | case WLR_INPUT_DEVICE_TABLET_TOOL: | 123 | case WLR_INPUT_DEVICE_TABLET: |
116 | return "tablet_tool"; | 124 | return "tablet_tool"; |
117 | case WLR_INPUT_DEVICE_TABLET_PAD: | 125 | case WLR_INPUT_DEVICE_TABLET_PAD: |
118 | return "tablet_pad"; | 126 | return "tablet_pad"; |
@@ -425,6 +433,20 @@ void handle_virtual_pointer(struct wl_listener *listener, void *data) { | |||
425 | } | 433 | } |
426 | } | 434 | } |
427 | 435 | ||
436 | static void handle_transient_seat_manager_create_seat( | ||
437 | struct wl_listener *listener, void *data) { | ||
438 | struct wlr_transient_seat_v1 *transient_seat = data; | ||
439 | static uint64_t i; | ||
440 | char name[256]; | ||
441 | snprintf(name, sizeof(name), "transient-%"PRIx64, i++); | ||
442 | struct sway_seat *seat = seat_create(name); | ||
443 | if (seat && seat->wlr_seat) { | ||
444 | wlr_transient_seat_v1_ready(transient_seat, seat->wlr_seat); | ||
445 | } else { | ||
446 | wlr_transient_seat_v1_deny(transient_seat); | ||
447 | } | ||
448 | } | ||
449 | |||
428 | struct sway_input_manager *input_manager_create(struct sway_server *server) { | 450 | struct sway_input_manager *input_manager_create(struct sway_server *server) { |
429 | struct sway_input_manager *input = | 451 | struct sway_input_manager *input = |
430 | calloc(1, sizeof(struct sway_input_manager)); | 452 | calloc(1, sizeof(struct sway_input_manager)); |
@@ -460,6 +482,15 @@ struct sway_input_manager *input_manager_create(struct sway_server *server) { | |||
460 | 482 | ||
461 | input->pointer_gestures = wlr_pointer_gestures_v1_create(server->wl_display); | 483 | input->pointer_gestures = wlr_pointer_gestures_v1_create(server->wl_display); |
462 | 484 | ||
485 | input->transient_seat_manager = | ||
486 | wlr_transient_seat_manager_v1_create(server->wl_display); | ||
487 | assert(input->transient_seat_manager); | ||
488 | |||
489 | input->transient_seat_create.notify = | ||
490 | handle_transient_seat_manager_create_seat; | ||
491 | wl_signal_add(&input->transient_seat_manager->events.create_seat, | ||
492 | &input->transient_seat_create); | ||
493 | |||
463 | return input; | 494 | return input; |
464 | } | 495 | } |
465 | 496 | ||
diff --git a/sway/input/seat.c b/sway/input/seat.c index 75fea484..0c5672bc 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <linux/input-event-codes.h> | 2 | #include <linux/input-event-codes.h> |
4 | #include <string.h> | 3 | #include <string.h> |
@@ -68,6 +67,12 @@ static void seat_node_destroy(struct sway_seat_node *seat_node) { | |||
68 | } | 67 | } |
69 | 68 | ||
70 | void seat_destroy(struct sway_seat *seat) { | 69 | void seat_destroy(struct sway_seat *seat) { |
70 | wlr_seat_destroy(seat->wlr_seat); | ||
71 | } | ||
72 | |||
73 | static void handle_seat_destroy(struct wl_listener *listener, void *data) { | ||
74 | struct sway_seat *seat = wl_container_of(listener, seat, destroy); | ||
75 | |||
71 | if (seat == config->handler_context.seat) { | 76 | if (seat == config->handler_context.seat) { |
72 | config->handler_context.seat = input_manager_get_default_seat(); | 77 | config->handler_context.seat = input_manager_get_default_seat(); |
73 | } | 78 | } |
@@ -88,7 +93,7 @@ void seat_destroy(struct sway_seat *seat) { | |||
88 | wl_list_remove(&seat->request_set_selection.link); | 93 | wl_list_remove(&seat->request_set_selection.link); |
89 | wl_list_remove(&seat->request_set_primary_selection.link); | 94 | wl_list_remove(&seat->request_set_primary_selection.link); |
90 | wl_list_remove(&seat->link); | 95 | wl_list_remove(&seat->link); |
91 | wlr_seat_destroy(seat->wlr_seat); | 96 | wl_list_remove(&seat->destroy.link); |
92 | for (int i = 0; i < seat->deferred_bindings->length; i++) { | 97 | for (int i = 0; i < seat->deferred_bindings->length; i++) { |
93 | free_sway_binding(seat->deferred_bindings->items[i]); | 98 | free_sway_binding(seat->deferred_bindings->items[i]); |
94 | } | 99 | } |
@@ -535,6 +540,9 @@ struct sway_seat *seat_create(const char *seat_name) { | |||
535 | return NULL; | 540 | return NULL; |
536 | } | 541 | } |
537 | 542 | ||
543 | seat->destroy.notify = handle_seat_destroy; | ||
544 | wl_signal_add(&seat->wlr_seat->events.destroy, &seat->destroy); | ||
545 | |||
538 | seat->idle_inhibit_sources = seat->idle_wake_sources = | 546 | seat->idle_inhibit_sources = seat->idle_wake_sources = |
539 | IDLE_SOURCE_KEYBOARD | | 547 | IDLE_SOURCE_KEYBOARD | |
540 | IDLE_SOURCE_POINTER | | 548 | IDLE_SOURCE_POINTER | |
@@ -608,7 +616,7 @@ static void seat_update_capabilities(struct sway_seat *seat) { | |||
608 | case WLR_INPUT_DEVICE_TOUCH: | 616 | case WLR_INPUT_DEVICE_TOUCH: |
609 | caps |= WL_SEAT_CAPABILITY_TOUCH; | 617 | caps |= WL_SEAT_CAPABILITY_TOUCH; |
610 | break; | 618 | break; |
611 | case WLR_INPUT_DEVICE_TABLET_TOOL: | 619 | case WLR_INPUT_DEVICE_TABLET: |
612 | caps |= WL_SEAT_CAPABILITY_POINTER; | 620 | caps |= WL_SEAT_CAPABILITY_POINTER; |
613 | break; | 621 | break; |
614 | case WLR_INPUT_DEVICE_SWITCH: | 622 | case WLR_INPUT_DEVICE_SWITCH: |
@@ -666,7 +674,7 @@ static const char *get_builtin_output_name(void) { | |||
666 | static bool is_touch_or_tablet_tool(struct sway_seat_device *seat_device) { | 674 | static bool is_touch_or_tablet_tool(struct sway_seat_device *seat_device) { |
667 | switch (seat_device->input_device->wlr_device->type) { | 675 | switch (seat_device->input_device->wlr_device->type) { |
668 | case WLR_INPUT_DEVICE_TOUCH: | 676 | case WLR_INPUT_DEVICE_TOUCH: |
669 | case WLR_INPUT_DEVICE_TABLET_TOOL: | 677 | case WLR_INPUT_DEVICE_TABLET: |
670 | return true; | 678 | return true; |
671 | default: | 679 | default: |
672 | return false; | 680 | return false; |
@@ -681,7 +689,7 @@ static void seat_apply_input_mapping(struct sway_seat *seat, | |||
681 | switch (sway_device->input_device->wlr_device->type) { | 689 | switch (sway_device->input_device->wlr_device->type) { |
682 | case WLR_INPUT_DEVICE_POINTER: | 690 | case WLR_INPUT_DEVICE_POINTER: |
683 | case WLR_INPUT_DEVICE_TOUCH: | 691 | case WLR_INPUT_DEVICE_TOUCH: |
684 | case WLR_INPUT_DEVICE_TABLET_TOOL: | 692 | case WLR_INPUT_DEVICE_TABLET: |
685 | break; | 693 | break; |
686 | default: | 694 | default: |
687 | return; // these devices don't support mappings | 695 | return; // these devices don't support mappings |
@@ -874,7 +882,7 @@ void seat_configure_device(struct sway_seat *seat, | |||
874 | case WLR_INPUT_DEVICE_TOUCH: | 882 | case WLR_INPUT_DEVICE_TOUCH: |
875 | seat_configure_touch(seat, seat_device); | 883 | seat_configure_touch(seat, seat_device); |
876 | break; | 884 | break; |
877 | case WLR_INPUT_DEVICE_TABLET_TOOL: | 885 | case WLR_INPUT_DEVICE_TABLET: |
878 | seat_configure_tablet_tool(seat, seat_device); | 886 | seat_configure_tablet_tool(seat, seat_device); |
879 | break; | 887 | break; |
880 | case WLR_INPUT_DEVICE_TABLET_PAD: | 888 | case WLR_INPUT_DEVICE_TABLET_PAD: |
@@ -913,7 +921,7 @@ void seat_reset_device(struct sway_seat *seat, | |||
913 | case WLR_INPUT_DEVICE_TOUCH: | 921 | case WLR_INPUT_DEVICE_TOUCH: |
914 | seat_reset_input_config(seat, seat_device); | 922 | seat_reset_input_config(seat, seat_device); |
915 | break; | 923 | break; |
916 | case WLR_INPUT_DEVICE_TABLET_TOOL: | 924 | case WLR_INPUT_DEVICE_TABLET: |
917 | seat_reset_input_config(seat, seat_device); | 925 | seat_reset_input_config(seat, seat_device); |
918 | break; | 926 | break; |
919 | case WLR_INPUT_DEVICE_TABLET_PAD: | 927 | case WLR_INPUT_DEVICE_TABLET_PAD: |
@@ -1521,7 +1529,7 @@ struct seat_config *seat_get_config_by_name(const char *name) { | |||
1521 | } | 1529 | } |
1522 | 1530 | ||
1523 | void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, | 1531 | void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, |
1524 | uint32_t button, enum wlr_button_state state) { | 1532 | uint32_t button, enum wl_pointer_button_state state) { |
1525 | seat->last_button_serial = wlr_seat_pointer_notify_button(seat->wlr_seat, | 1533 | seat->last_button_serial = wlr_seat_pointer_notify_button(seat->wlr_seat, |
1526 | time_msec, button, state); | 1534 | time_msec, button, state); |
1527 | } | 1535 | } |
@@ -1558,7 +1566,7 @@ void seatop_unref(struct sway_seat *seat, struct sway_container *con) { | |||
1558 | 1566 | ||
1559 | void seatop_button(struct sway_seat *seat, uint32_t time_msec, | 1567 | void seatop_button(struct sway_seat *seat, uint32_t time_msec, |
1560 | struct wlr_input_device *device, uint32_t button, | 1568 | struct wlr_input_device *device, uint32_t button, |
1561 | enum wlr_button_state state) { | 1569 | enum wl_pointer_button_state state) { |
1562 | if (seat->seatop_impl->button) { | 1570 | if (seat->seatop_impl->button) { |
1563 | seat->seatop_impl->button(seat, time_msec, device, button, state); | 1571 | seat->seatop_impl->button(seat, time_msec, device, button, state); |
1564 | } | 1572 | } |
diff --git a/sway/input/seatop_default.c b/sway/input/seatop_default.c index c56330fd..0c6f7c5e 100644 --- a/sway/input/seatop_default.c +++ b/sway/input/seatop_default.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <float.h> | 1 | #include <float.h> |
3 | #include <libevdev/libevdev.h> | 2 | #include <libevdev/libevdev.h> |
4 | #include <wlr/types/wlr_cursor.h> | 3 | #include <wlr/types/wlr_cursor.h> |
@@ -291,7 +290,7 @@ static void handle_tablet_tool_tip(struct sway_seat *seat, | |||
291 | 290 | ||
292 | static bool trigger_pointer_button_binding(struct sway_seat *seat, | 291 | static bool trigger_pointer_button_binding(struct sway_seat *seat, |
293 | struct wlr_input_device *device, uint32_t button, | 292 | struct wlr_input_device *device, uint32_t button, |
294 | enum wlr_button_state state, uint32_t modifiers, | 293 | enum wl_pointer_button_state state, uint32_t modifiers, |
295 | bool on_titlebar, bool on_border, bool on_contents, bool on_workspace) { | 294 | bool on_titlebar, bool on_border, bool on_contents, bool on_workspace) { |
296 | // We can reach this for non-pointer devices if we're currently emulating | 295 | // We can reach this for non-pointer devices if we're currently emulating |
297 | // pointer input for one. Emulated input should not trigger bindings. The | 296 | // pointer input for one. Emulated input should not trigger bindings. The |
@@ -305,7 +304,7 @@ static bool trigger_pointer_button_binding(struct sway_seat *seat, | |||
305 | char *device_identifier = device ? input_device_get_identifier(device) | 304 | char *device_identifier = device ? input_device_get_identifier(device) |
306 | : strdup("*"); | 305 | : strdup("*"); |
307 | struct sway_binding *binding = NULL; | 306 | struct sway_binding *binding = NULL; |
308 | if (state == WLR_BUTTON_PRESSED) { | 307 | if (state == WL_POINTER_BUTTON_STATE_PRESSED) { |
309 | state_add_button(e, button); | 308 | state_add_button(e, button); |
310 | binding = get_active_mouse_binding(e, | 309 | binding = get_active_mouse_binding(e, |
311 | config->current_mode->mouse_bindings, modifiers, false, | 310 | config->current_mode->mouse_bindings, modifiers, false, |
@@ -330,7 +329,7 @@ static bool trigger_pointer_button_binding(struct sway_seat *seat, | |||
330 | 329 | ||
331 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, | 330 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, |
332 | struct wlr_input_device *device, uint32_t button, | 331 | struct wlr_input_device *device, uint32_t button, |
333 | enum wlr_button_state state) { | 332 | enum wl_pointer_button_state state) { |
334 | struct sway_cursor *cursor = seat->cursor; | 333 | struct sway_cursor *cursor = seat->cursor; |
335 | 334 | ||
336 | // Determine what's under the cursor | 335 | // Determine what's under the cursor |
@@ -363,7 +362,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, | |||
363 | 362 | ||
364 | // Handle clicking an empty workspace | 363 | // Handle clicking an empty workspace |
365 | if (node && node->type == N_WORKSPACE) { | 364 | if (node && node->type == N_WORKSPACE) { |
366 | if (state == WLR_BUTTON_PRESSED) { | 365 | if (state == WL_POINTER_BUTTON_STATE_PRESSED) { |
367 | seat_set_focus(seat, node); | 366 | seat_set_focus(seat, node); |
368 | transaction_commit_dirty(); | 367 | transaction_commit_dirty(); |
369 | } | 368 | } |
@@ -378,7 +377,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, | |||
378 | seat_set_focus_layer(seat, layer); | 377 | seat_set_focus_layer(seat, layer); |
379 | transaction_commit_dirty(); | 378 | transaction_commit_dirty(); |
380 | } | 379 | } |
381 | if (state == WLR_BUTTON_PRESSED) { | 380 | if (state == WL_POINTER_BUTTON_STATE_PRESSED) { |
382 | seatop_begin_down_on_surface(seat, surface, sx, sy); | 381 | seatop_begin_down_on_surface(seat, surface, sx, sy); |
383 | } | 382 | } |
384 | seat_pointer_notify_button(seat, time_msec, button, state); | 383 | seat_pointer_notify_button(seat, time_msec, button, state); |
@@ -387,7 +386,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, | |||
387 | 386 | ||
388 | // Handle tiling resize via border | 387 | // Handle tiling resize via border |
389 | if (cont && resize_edge && button == BTN_LEFT && | 388 | if (cont && resize_edge && button == BTN_LEFT && |
390 | state == WLR_BUTTON_PRESSED && !is_floating) { | 389 | state == WL_POINTER_BUTTON_STATE_PRESSED && !is_floating) { |
391 | // If a resize is triggered on a tabbed or stacked container, change | 390 | // If a resize is triggered on a tabbed or stacked container, change |
392 | // focus to the tab which already had inactive focus -- otherwise, we'd | 391 | // focus to the tab which already had inactive focus -- otherwise, we'd |
393 | // change the active tab when the user probably just wanted to resize. | 392 | // change the active tab when the user probably just wanted to resize. |
@@ -405,7 +404,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, | |||
405 | // Handle tiling resize via mod | 404 | // Handle tiling resize via mod |
406 | bool mod_pressed = modifiers & config->floating_mod; | 405 | bool mod_pressed = modifiers & config->floating_mod; |
407 | if (cont && !is_floating_or_child && mod_pressed && | 406 | if (cont && !is_floating_or_child && mod_pressed && |
408 | state == WLR_BUTTON_PRESSED) { | 407 | state == WL_POINTER_BUTTON_STATE_PRESSED) { |
409 | uint32_t btn_resize = config->floating_mod_inverse ? | 408 | uint32_t btn_resize = config->floating_mod_inverse ? |
410 | BTN_LEFT : BTN_RIGHT; | 409 | BTN_LEFT : BTN_RIGHT; |
411 | if (button == btn_resize) { | 410 | if (button == btn_resize) { |
@@ -433,7 +432,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, | |||
433 | } | 432 | } |
434 | 433 | ||
435 | // Handle changing focus when clicking on a container | 434 | // Handle changing focus when clicking on a container |
436 | if (cont && state == WLR_BUTTON_PRESSED) { | 435 | if (cont && state == WL_POINTER_BUTTON_STATE_PRESSED) { |
437 | // Default case: focus the container that was just clicked. | 436 | // Default case: focus the container that was just clicked. |
438 | node = &cont->node; | 437 | node = &cont->node; |
439 | 438 | ||
@@ -454,7 +453,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, | |||
454 | 453 | ||
455 | // Handle beginning floating move | 454 | // Handle beginning floating move |
456 | if (cont && is_floating_or_child && !is_fullscreen_or_child && | 455 | if (cont && is_floating_or_child && !is_fullscreen_or_child && |
457 | state == WLR_BUTTON_PRESSED) { | 456 | state == WL_POINTER_BUTTON_STATE_PRESSED) { |
458 | uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT; | 457 | uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT; |
459 | if (button == btn_move && (mod_pressed || on_titlebar)) { | 458 | if (button == btn_move && (mod_pressed || on_titlebar)) { |
460 | seatop_begin_move_floating(seat, container_toplevel_ancestor(cont)); | 459 | seatop_begin_move_floating(seat, container_toplevel_ancestor(cont)); |
@@ -464,7 +463,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, | |||
464 | 463 | ||
465 | // Handle beginning floating resize | 464 | // Handle beginning floating resize |
466 | if (cont && is_floating_or_child && !is_fullscreen_or_child && | 465 | if (cont && is_floating_or_child && !is_fullscreen_or_child && |
467 | state == WLR_BUTTON_PRESSED) { | 466 | state == WL_POINTER_BUTTON_STATE_PRESSED) { |
468 | // Via border | 467 | // Via border |
469 | if (button == BTN_LEFT && resize_edge != WLR_EDGE_NONE) { | 468 | if (button == BTN_LEFT && resize_edge != WLR_EDGE_NONE) { |
470 | seat_set_focus_container(seat, cont); | 469 | seat_set_focus_container(seat, cont); |
@@ -490,7 +489,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, | |||
490 | 489 | ||
491 | // Handle moving a tiling container | 490 | // Handle moving a tiling container |
492 | if (config->tiling_drag && (mod_pressed || on_titlebar) && | 491 | if (config->tiling_drag && (mod_pressed || on_titlebar) && |
493 | state == WLR_BUTTON_PRESSED && !is_floating_or_child && | 492 | state == WL_POINTER_BUTTON_STATE_PRESSED && !is_floating_or_child && |
494 | cont && cont->pending.fullscreen_mode == FULLSCREEN_NONE) { | 493 | cont && cont->pending.fullscreen_mode == FULLSCREEN_NONE) { |
495 | // If moving a container by its title bar, use a threshold for the drag | 494 | // If moving a container by its title bar, use a threshold for the drag |
496 | if (!mod_pressed && config->tiling_drag_threshold > 0) { | 495 | if (!mod_pressed && config->tiling_drag_threshold > 0) { |
@@ -503,14 +502,14 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, | |||
503 | } | 502 | } |
504 | 503 | ||
505 | // Handle mousedown on a container surface | 504 | // Handle mousedown on a container surface |
506 | if (surface && cont && state == WLR_BUTTON_PRESSED) { | 505 | if (surface && cont && state == WL_POINTER_BUTTON_STATE_PRESSED) { |
507 | seatop_begin_down(seat, cont, sx, sy); | 506 | seatop_begin_down(seat, cont, sx, sy); |
508 | seat_pointer_notify_button(seat, time_msec, button, WLR_BUTTON_PRESSED); | 507 | seat_pointer_notify_button(seat, time_msec, button, WL_POINTER_BUTTON_STATE_PRESSED); |
509 | return; | 508 | return; |
510 | } | 509 | } |
511 | 510 | ||
512 | // Handle clicking a container surface or decorations | 511 | // Handle clicking a container surface or decorations |
513 | if (cont && state == WLR_BUTTON_PRESSED) { | 512 | if (cont && state == WL_POINTER_BUTTON_STATE_PRESSED) { |
514 | seat_pointer_notify_button(seat, time_msec, button, state); | 513 | seat_pointer_notify_button(seat, time_msec, button, state); |
515 | return; | 514 | return; |
516 | } | 515 | } |
@@ -685,7 +684,7 @@ static void handle_touch_down(struct sway_seat *seat, | |||
685 | pointer_motion(cursor, event->time_msec, &event->touch->base, dx, dy, | 684 | pointer_motion(cursor, event->time_msec, &event->touch->base, dx, dy, |
686 | dx, dy); | 685 | dx, dy); |
687 | dispatch_cursor_button(cursor, &event->touch->base, event->time_msec, | 686 | dispatch_cursor_button(cursor, &event->touch->base, event->time_msec, |
688 | BTN_LEFT, WLR_BUTTON_PRESSED); | 687 | BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); |
689 | } | 688 | } |
690 | } | 689 | } |
691 | 690 | ||
@@ -695,9 +694,9 @@ static void handle_touch_down(struct sway_seat *seat, | |||
695 | 694 | ||
696 | static uint32_t wl_axis_to_button(struct wlr_pointer_axis_event *event) { | 695 | static uint32_t wl_axis_to_button(struct wlr_pointer_axis_event *event) { |
697 | switch (event->orientation) { | 696 | switch (event->orientation) { |
698 | case WLR_AXIS_ORIENTATION_VERTICAL: | 697 | case WL_POINTER_AXIS_VERTICAL_SCROLL: |
699 | return event->delta < 0 ? SWAY_SCROLL_UP : SWAY_SCROLL_DOWN; | 698 | return event->delta < 0 ? SWAY_SCROLL_UP : SWAY_SCROLL_DOWN; |
700 | case WLR_AXIS_ORIENTATION_HORIZONTAL: | 699 | case WL_POINTER_AXIS_HORIZONTAL_SCROLL: |
701 | return event->delta < 0 ? SWAY_SCROLL_LEFT : SWAY_SCROLL_RIGHT; | 700 | return event->delta < 0 ? SWAY_SCROLL_LEFT : SWAY_SCROLL_RIGHT; |
702 | default: | 701 | default: |
703 | sway_log(SWAY_DEBUG, "Unknown axis orientation"); | 702 | sway_log(SWAY_DEBUG, "Unknown axis orientation"); |
diff --git a/sway/input/seatop_down.c b/sway/input/seatop_down.c index b4421fe6..35fd3bcb 100644 --- a/sway/input/seatop_down.c +++ b/sway/input/seatop_down.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <float.h> | 1 | #include <float.h> |
3 | #include <wlr/types/wlr_cursor.h> | 2 | #include <wlr/types/wlr_cursor.h> |
4 | #include <wlr/types/wlr_tablet_v2.h> | 3 | #include <wlr/types/wlr_tablet_v2.h> |
@@ -143,7 +142,7 @@ static void handle_pointer_axis(struct sway_seat *seat, | |||
143 | 142 | ||
144 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, | 143 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, |
145 | struct wlr_input_device *device, uint32_t button, | 144 | struct wlr_input_device *device, uint32_t button, |
146 | enum wlr_button_state state) { | 145 | enum wl_pointer_button_state state) { |
147 | seat_pointer_notify_button(seat, time_msec, button, state); | 146 | seat_pointer_notify_button(seat, time_msec, button, state); |
148 | 147 | ||
149 | if (seat->cursor->pressed_button_count == 0) { | 148 | if (seat->cursor->pressed_button_count == 0) { |
diff --git a/sway/input/seatop_move_floating.c b/sway/input/seatop_move_floating.c index 21d048ce..83668d88 100644 --- a/sway/input/seatop_move_floating.c +++ b/sway/input/seatop_move_floating.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <wlr/types/wlr_cursor.h> | 1 | #include <wlr/types/wlr_cursor.h> |
3 | #include "sway/desktop/transaction.h" | 2 | #include "sway/desktop/transaction.h" |
4 | #include "sway/input/cursor.h" | 3 | #include "sway/input/cursor.h" |
@@ -22,7 +21,7 @@ static void finalize_move(struct sway_seat *seat) { | |||
22 | 21 | ||
23 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, | 22 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, |
24 | struct wlr_input_device *device, uint32_t button, | 23 | struct wlr_input_device *device, uint32_t button, |
25 | enum wlr_button_state state) { | 24 | enum wl_pointer_button_state state) { |
26 | if (seat->cursor->pressed_button_count == 0) { | 25 | if (seat->cursor->pressed_button_count == 0) { |
27 | finalize_move(seat); | 26 | finalize_move(seat); |
28 | } | 27 | } |
diff --git a/sway/input/seatop_move_tiling.c b/sway/input/seatop_move_tiling.c index 7de39ff6..c525b77a 100644 --- a/sway/input/seatop_move_tiling.c +++ b/sway/input/seatop_move_tiling.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <limits.h> | 1 | #include <limits.h> |
3 | #include <wlr/types/wlr_cursor.h> | 2 | #include <wlr/types/wlr_cursor.h> |
4 | #include <wlr/util/edges.h> | 3 | #include <wlr/util/edges.h> |
@@ -406,7 +405,7 @@ static void finalize_move(struct sway_seat *seat) { | |||
406 | 405 | ||
407 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, | 406 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, |
408 | struct wlr_input_device *device, uint32_t button, | 407 | struct wlr_input_device *device, uint32_t button, |
409 | enum wlr_button_state state) { | 408 | enum wl_pointer_button_state state) { |
410 | if (seat->cursor->pressed_button_count == 0) { | 409 | if (seat->cursor->pressed_button_count == 0) { |
411 | finalize_move(seat); | 410 | finalize_move(seat); |
412 | } | 411 | } |
diff --git a/sway/input/seatop_resize_floating.c b/sway/input/seatop_resize_floating.c index df683026..bec86e33 100644 --- a/sway/input/seatop_resize_floating.c +++ b/sway/input/seatop_resize_floating.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <limits.h> | 1 | #include <limits.h> |
3 | #include <wlr/types/wlr_cursor.h> | 2 | #include <wlr/types/wlr_cursor.h> |
4 | #include <wlr/types/wlr_xcursor_manager.h> | 3 | #include <wlr/types/wlr_xcursor_manager.h> |
@@ -21,7 +20,7 @@ struct seatop_resize_floating_event { | |||
21 | 20 | ||
22 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, | 21 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, |
23 | struct wlr_input_device *device, uint32_t button, | 22 | struct wlr_input_device *device, uint32_t button, |
24 | enum wlr_button_state state) { | 23 | enum wl_pointer_button_state state) { |
25 | struct seatop_resize_floating_event *e = seat->seatop_data; | 24 | struct seatop_resize_floating_event *e = seat->seatop_data; |
26 | struct sway_container *con = e->con; | 25 | struct sway_container *con = e->con; |
27 | 26 | ||
diff --git a/sway/input/seatop_resize_tiling.c b/sway/input/seatop_resize_tiling.c index 869d11b5..15fd333b 100644 --- a/sway/input/seatop_resize_tiling.c +++ b/sway/input/seatop_resize_tiling.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <wlr/types/wlr_cursor.h> | 1 | #include <wlr/types/wlr_cursor.h> |
3 | #include <wlr/util/edges.h> | 2 | #include <wlr/util/edges.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
@@ -46,7 +45,7 @@ static struct sway_container *container_get_resize_sibling( | |||
46 | 45 | ||
47 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, | 46 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, |
48 | struct wlr_input_device *device, uint32_t button, | 47 | struct wlr_input_device *device, uint32_t button, |
49 | enum wlr_button_state state) { | 48 | enum wl_pointer_button_state state) { |
50 | struct seatop_resize_tiling_event *e = seat->seatop_data; | 49 | struct seatop_resize_tiling_event *e = seat->seatop_data; |
51 | 50 | ||
52 | if (seat->cursor->pressed_button_count == 0) { | 51 | if (seat->cursor->pressed_button_count == 0) { |
diff --git a/sway/input/tablet.c b/sway/input/tablet.c index 902cb7ed..2863642a 100644 --- a/sway/input/tablet.c +++ b/sway/input/tablet.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdlib.h> | 1 | #include <stdlib.h> |
3 | #include <wlr/config.h> | 2 | #include <wlr/config.h> |
4 | #include <wlr/types/wlr_tablet_v2.h> | 3 | #include <wlr/types/wlr_tablet_v2.h> |
diff --git a/sway/input/text_input.c b/sway/input/text_input.c index 58911c2d..c38a3bb2 100644 --- a/sway/input/text_input.c +++ b/sway/input/text_input.c | |||
@@ -2,7 +2,14 @@ | |||
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include "log.h" | 3 | #include "log.h" |
4 | #include "sway/input/seat.h" | 4 | #include "sway/input/seat.h" |
5 | #include "sway/scene_descriptor.h" | ||
6 | #include "sway/tree/root.h" | ||
7 | #include "sway/tree/view.h" | ||
8 | #include "sway/output.h" | ||
5 | #include "sway/input/text_input.h" | 9 | #include "sway/input/text_input.h" |
10 | #include "sway/input/text_input_popup.h" | ||
11 | #include "sway/layers.h" | ||
12 | static void input_popup_update(struct sway_input_popup *popup); | ||
6 | 13 | ||
7 | static struct sway_text_input *relay_get_focusable_text_input( | 14 | static struct sway_text_input *relay_get_focusable_text_input( |
8 | struct sway_input_method_relay *relay) { | 15 | struct sway_input_method_relay *relay) { |
@@ -102,6 +109,10 @@ static void handle_im_destroy(struct wl_listener *listener, void *data) { | |||
102 | input_method_destroy); | 109 | input_method_destroy); |
103 | struct wlr_input_method_v2 *context = data; | 110 | struct wlr_input_method_v2 *context = data; |
104 | assert(context == relay->input_method); | 111 | assert(context == relay->input_method); |
112 | wl_list_remove(&relay->input_method_commit.link); | ||
113 | wl_list_remove(&relay->input_method_grab_keyboard.link); | ||
114 | wl_list_remove(&relay->input_method_destroy.link); | ||
115 | wl_list_remove(&relay->input_method_new_popup_surface.link); | ||
105 | relay->input_method = NULL; | 116 | relay->input_method = NULL; |
106 | struct sway_text_input *text_input = relay_get_focused_text_input(relay); | 117 | struct sway_text_input *text_input = relay_get_focused_text_input(relay); |
107 | if (text_input) { | 118 | if (text_input) { |
@@ -133,6 +144,11 @@ static void relay_send_im_state(struct sway_input_method_relay *relay, | |||
133 | input->current.content_type.hint, | 144 | input->current.content_type.hint, |
134 | input->current.content_type.purpose); | 145 | input->current.content_type.purpose); |
135 | } | 146 | } |
147 | struct sway_input_popup *popup; | ||
148 | wl_list_for_each(popup, &relay->input_popups, link) { | ||
149 | // send_text_input_rectangle is called in this function | ||
150 | input_popup_update(popup); | ||
151 | } | ||
136 | wlr_input_method_v2_send_done(input_method); | 152 | wlr_input_method_v2_send_done(input_method); |
137 | // TODO: pass intent, display popup size | 153 | // TODO: pass intent, display popup size |
138 | } | 154 | } |
@@ -255,6 +271,211 @@ static void relay_handle_text_input(struct wl_listener *listener, | |||
255 | sway_text_input_create(relay, wlr_text_input); | 271 | sway_text_input_create(relay, wlr_text_input); |
256 | } | 272 | } |
257 | 273 | ||
274 | static void input_popup_update(struct sway_input_popup *popup) { | ||
275 | struct sway_text_input *text_input = | ||
276 | relay_get_focused_text_input(popup->relay); | ||
277 | |||
278 | if (text_input == NULL || text_input->input->focused_surface == NULL) { | ||
279 | return; | ||
280 | } | ||
281 | |||
282 | if (popup->scene_tree != NULL) { | ||
283 | wlr_scene_node_destroy(&popup->scene_tree->node); | ||
284 | popup->scene_tree = NULL; | ||
285 | } | ||
286 | if (popup->desc.relative != NULL) { | ||
287 | wlr_scene_node_destroy(popup->desc.relative); | ||
288 | popup->desc.relative = NULL; | ||
289 | } | ||
290 | popup->desc.view = NULL; | ||
291 | |||
292 | if (!popup->popup_surface->surface->mapped) { | ||
293 | return; | ||
294 | } | ||
295 | |||
296 | bool cursor_rect = text_input->input->current.features | ||
297 | & WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE; | ||
298 | struct wlr_surface *focused_surface = text_input->input->focused_surface; | ||
299 | struct wlr_box cursor_area = text_input->input->current.cursor_rectangle; | ||
300 | |||
301 | struct wlr_box output_box; | ||
302 | struct wlr_box parent = {0}; | ||
303 | struct wlr_layer_surface_v1 *layer_surface = | ||
304 | wlr_layer_surface_v1_try_from_wlr_surface(focused_surface); | ||
305 | struct wlr_scene_tree *relative_parent; | ||
306 | |||
307 | struct wlr_box geo = {0}; | ||
308 | |||
309 | popup->scene_tree = wlr_scene_subsurface_tree_create(root->layers.popup, popup->popup_surface->surface); | ||
310 | if (layer_surface != NULL) { | ||
311 | struct sway_layer_surface *layer = | ||
312 | layer_surface->data; | ||
313 | if (layer == NULL) { | ||
314 | return; | ||
315 | } | ||
316 | |||
317 | relative_parent = layer->scene->tree; | ||
318 | struct wlr_output *output = layer->layer_surface->output; | ||
319 | wlr_output_layout_get_box(root->output_layout, output, &output_box); | ||
320 | int lx, ly; | ||
321 | wlr_scene_node_coords(&layer->tree->node, &lx, &ly); | ||
322 | parent.x = lx; | ||
323 | parent.y = ly; | ||
324 | popup->desc.view = NULL; | ||
325 | } else { | ||
326 | struct sway_view *view = view_from_wlr_surface(focused_surface); | ||
327 | relative_parent = view->scene_tree; | ||
328 | geo = view->geometry; | ||
329 | int lx, ly; | ||
330 | wlr_scene_node_coords(&view->scene_tree->node, &lx, &ly); | ||
331 | struct wlr_output *output = wlr_output_layout_output_at(root->output_layout, | ||
332 | view->container->pending.content_x + view->geometry.x, | ||
333 | view->container->pending.content_y + view->geometry.y); | ||
334 | wlr_output_layout_get_box(root->output_layout, output, &output_box); | ||
335 | parent.x = lx; | ||
336 | parent.y = ly; | ||
337 | |||
338 | parent.width = view->geometry.width; | ||
339 | parent.height = view->geometry.height; | ||
340 | popup->desc.view = view; | ||
341 | } | ||
342 | |||
343 | struct wlr_scene_tree *relative = wlr_scene_tree_create(relative_parent); | ||
344 | |||
345 | popup->desc.relative = &relative->node; | ||
346 | if (!scene_descriptor_assign(&popup->scene_tree->node, | ||
347 | SWAY_SCENE_DESC_POPUP, &popup->desc)) { | ||
348 | wlr_scene_node_destroy(&popup->scene_tree->node); | ||
349 | popup->scene_tree = NULL; | ||
350 | return; | ||
351 | } | ||
352 | |||
353 | if (!cursor_rect) { | ||
354 | cursor_area.x = 0; | ||
355 | cursor_area.y = 0; | ||
356 | cursor_area.width = parent.width; | ||
357 | cursor_area.height = parent.height; | ||
358 | } | ||
359 | |||
360 | int popup_width = popup->popup_surface->surface->current.width; | ||
361 | int popup_height = popup->popup_surface->surface->current.height; | ||
362 | int x1 = parent.x + cursor_area.x; | ||
363 | int x2 = parent.x + cursor_area.x + cursor_area.width; | ||
364 | int y1 = parent.y + cursor_area.y; | ||
365 | int y2 = parent.y + cursor_area.y + cursor_area.height; | ||
366 | int x = x1; | ||
367 | int y = y2; | ||
368 | |||
369 | int available_right = output_box.x + output_box.width - x1; | ||
370 | int available_left = x2 - output_box.x; | ||
371 | if (available_right < popup_width && available_left > available_right) { | ||
372 | x = x2 - popup_width; | ||
373 | } | ||
374 | |||
375 | int available_down = output_box.y + output_box.height - y2; | ||
376 | int available_up = y1 - output_box.y; | ||
377 | if (available_down < popup_height && available_up > available_down) { | ||
378 | y = y1 - popup_height; | ||
379 | } | ||
380 | |||
381 | wlr_scene_node_set_position(&relative->node, x - parent.x - geo.x, y - parent.y - geo.y); | ||
382 | if (cursor_rect) { | ||
383 | struct wlr_box box = { | ||
384 | .x = x1 - x, | ||
385 | .y = y1 - y, | ||
386 | .width = cursor_area.width, | ||
387 | .height = cursor_area.height, | ||
388 | }; | ||
389 | wlr_input_popup_surface_v2_send_text_input_rectangle( | ||
390 | popup->popup_surface, &box); | ||
391 | } | ||
392 | wlr_scene_node_set_position(&popup->scene_tree->node, x - geo.x, y - geo.y); | ||
393 | } | ||
394 | |||
395 | static void input_popup_set_focus(struct sway_input_popup *popup, | ||
396 | struct wlr_surface *surface) { | ||
397 | wl_list_remove(&popup->focused_surface_unmap.link); | ||
398 | |||
399 | if (surface == NULL) { | ||
400 | wl_list_init(&popup->focused_surface_unmap.link); | ||
401 | input_popup_update(popup); | ||
402 | return; | ||
403 | } | ||
404 | struct wlr_layer_surface_v1 *layer_surface = | ||
405 | wlr_layer_surface_v1_try_from_wlr_surface(surface); | ||
406 | if (layer_surface != NULL) { | ||
407 | wl_signal_add( | ||
408 | &layer_surface->surface->events.unmap, &popup->focused_surface_unmap); | ||
409 | input_popup_update(popup); | ||
410 | return; | ||
411 | } | ||
412 | |||
413 | struct sway_view *view = view_from_wlr_surface(surface); | ||
414 | wl_signal_add(&view->events.unmap, &popup->focused_surface_unmap); | ||
415 | } | ||
416 | |||
417 | static void handle_im_popup_destroy(struct wl_listener *listener, void *data) { | ||
418 | struct sway_input_popup *popup = | ||
419 | wl_container_of(listener, popup, popup_destroy); | ||
420 | wl_list_remove(&popup->focused_surface_unmap.link); | ||
421 | wl_list_remove(&popup->popup_surface_commit.link); | ||
422 | wl_list_remove(&popup->popup_destroy.link); | ||
423 | wl_list_remove(&popup->link); | ||
424 | |||
425 | free(popup); | ||
426 | } | ||
427 | |||
428 | static void handle_im_popup_surface_commit(struct wl_listener *listener, | ||
429 | void *data) { | ||
430 | struct sway_input_popup *popup = | ||
431 | wl_container_of(listener, popup, popup_surface_commit); | ||
432 | input_popup_update(popup); | ||
433 | } | ||
434 | |||
435 | static void handle_im_focused_surface_unmap( | ||
436 | struct wl_listener *listener, void *data) { | ||
437 | struct sway_input_popup *popup = | ||
438 | wl_container_of(listener, popup, focused_surface_unmap); | ||
439 | input_popup_update(popup); | ||
440 | } | ||
441 | |||
442 | static void handle_im_new_popup_surface(struct wl_listener *listener, | ||
443 | void *data) { | ||
444 | struct sway_input_method_relay *relay = wl_container_of(listener, relay, | ||
445 | input_method_new_popup_surface); | ||
446 | struct sway_input_popup *popup = calloc(1, sizeof(*popup)); | ||
447 | popup->relay = relay; | ||
448 | popup->popup_surface = data; | ||
449 | popup->popup_surface->data = popup; | ||
450 | |||
451 | wl_signal_add( | ||
452 | &popup->popup_surface->events.destroy, &popup->popup_destroy); | ||
453 | popup->popup_destroy.notify = handle_im_popup_destroy; | ||
454 | wl_signal_add(&popup->popup_surface->surface->events.commit, | ||
455 | &popup->popup_surface_commit); | ||
456 | popup->popup_surface_commit.notify = handle_im_popup_surface_commit; | ||
457 | wl_list_init(&popup->focused_surface_unmap.link); | ||
458 | popup->focused_surface_unmap.notify = handle_im_focused_surface_unmap; | ||
459 | |||
460 | struct sway_text_input *text_input = relay_get_focused_text_input(relay); | ||
461 | if (text_input != NULL) { | ||
462 | input_popup_set_focus(popup, text_input->input->focused_surface); | ||
463 | } else { | ||
464 | input_popup_set_focus(popup, NULL); | ||
465 | } | ||
466 | |||
467 | wl_list_insert(&relay->input_popups, &popup->link); | ||
468 | } | ||
469 | |||
470 | static void text_input_send_enter(struct sway_text_input *text_input, | ||
471 | struct wlr_surface *surface) { | ||
472 | wlr_text_input_v3_send_enter(text_input->input, surface); | ||
473 | struct sway_input_popup *popup; | ||
474 | wl_list_for_each(popup, &text_input->relay->input_popups, link) { | ||
475 | input_popup_set_focus(popup, surface); | ||
476 | } | ||
477 | } | ||
478 | |||
258 | static void relay_handle_input_method(struct wl_listener *listener, | 479 | static void relay_handle_input_method(struct wl_listener *listener, |
259 | void *data) { | 480 | void *data) { |
260 | struct sway_input_method_relay *relay = wl_container_of(listener, relay, | 481 | struct sway_input_method_relay *relay = wl_container_of(listener, relay, |
@@ -280,10 +501,13 @@ static void relay_handle_input_method(struct wl_listener *listener, | |||
280 | wl_signal_add(&relay->input_method->events.destroy, | 501 | wl_signal_add(&relay->input_method->events.destroy, |
281 | &relay->input_method_destroy); | 502 | &relay->input_method_destroy); |
282 | relay->input_method_destroy.notify = handle_im_destroy; | 503 | relay->input_method_destroy.notify = handle_im_destroy; |
504 | wl_signal_add(&relay->input_method->events.new_popup_surface, | ||
505 | &relay->input_method_new_popup_surface); | ||
506 | relay->input_method_new_popup_surface.notify = handle_im_new_popup_surface; | ||
283 | 507 | ||
284 | struct sway_text_input *text_input = relay_get_focusable_text_input(relay); | 508 | struct sway_text_input *text_input = relay_get_focusable_text_input(relay); |
285 | if (text_input) { | 509 | if (text_input) { |
286 | wlr_text_input_v3_send_enter(text_input->input, | 510 | text_input_send_enter(text_input, |
287 | text_input->pending_focused_surface); | 511 | text_input->pending_focused_surface); |
288 | text_input_set_pending_focused_surface(text_input, NULL); | 512 | text_input_set_pending_focused_surface(text_input, NULL); |
289 | } | 513 | } |
@@ -293,6 +517,7 @@ void sway_input_method_relay_init(struct sway_seat *seat, | |||
293 | struct sway_input_method_relay *relay) { | 517 | struct sway_input_method_relay *relay) { |
294 | relay->seat = seat; | 518 | relay->seat = seat; |
295 | wl_list_init(&relay->text_inputs); | 519 | wl_list_init(&relay->text_inputs); |
520 | wl_list_init(&relay->input_popups); | ||
296 | 521 | ||
297 | relay->text_input_new.notify = relay_handle_text_input; | 522 | relay->text_input_new.notify = relay_handle_text_input; |
298 | wl_signal_add(&server.text_input->events.text_input, | 523 | wl_signal_add(&server.text_input->events.text_input, |
diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 58356d4e..81ca3483 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c | |||
@@ -288,6 +288,8 @@ static json_object *ipc_json_create_node(int id, const char* type, char *name, | |||
288 | json_object_object_add(object, "focus", focus); | 288 | json_object_object_add(object, "focus", focus); |
289 | json_object_object_add(object, "fullscreen_mode", json_object_new_int(0)); | 289 | json_object_object_add(object, "fullscreen_mode", json_object_new_int(0)); |
290 | json_object_object_add(object, "sticky", json_object_new_boolean(false)); | 290 | json_object_object_add(object, "sticky", json_object_new_boolean(false)); |
291 | json_object_object_add(object, "floating", NULL); | ||
292 | json_object_object_add(object, "scratchpad_state", NULL); | ||
291 | 293 | ||
292 | return object; | 294 | return object; |
293 | } | 295 | } |
@@ -675,7 +677,8 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object | |||
675 | static void ipc_json_describe_container(struct sway_container *c, json_object *object) { | 677 | static void ipc_json_describe_container(struct sway_container *c, json_object *object) { |
676 | json_object_object_add(object, "name", | 678 | json_object_object_add(object, "name", |
677 | c->title ? json_object_new_string(c->title) : NULL); | 679 | c->title ? json_object_new_string(c->title) : NULL); |
678 | if (container_is_floating(c)) { | 680 | bool floating = container_is_floating(c); |
681 | if (floating) { | ||
679 | json_object_object_add(object, "type", | 682 | json_object_object_add(object, "type", |
680 | json_object_new_string("floating_con")); | 683 | json_object_new_string("floating_con")); |
681 | } | 684 | } |
@@ -693,9 +696,17 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o | |||
693 | json_object_object_add(object, "urgent", json_object_new_boolean(urgent)); | 696 | json_object_object_add(object, "urgent", json_object_new_boolean(urgent)); |
694 | json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky)); | 697 | json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky)); |
695 | 698 | ||
699 | // sway doesn't track the floating reason, so we can't use "auto_on" or "user_off" | ||
700 | json_object_object_add(object, "floating", | ||
701 | json_object_new_string(floating ? "user_on" : "auto_off")); | ||
702 | |||
696 | json_object_object_add(object, "fullscreen_mode", | 703 | json_object_object_add(object, "fullscreen_mode", |
697 | json_object_new_int(c->pending.fullscreen_mode)); | 704 | json_object_new_int(c->pending.fullscreen_mode)); |
698 | 705 | ||
706 | // sway doesn't track if window was resized in scratchpad, so we can't use "changed" | ||
707 | json_object_object_add(object, "scratchpad_state", | ||
708 | json_object_new_string(!c->scratchpad ? "none" : "fresh")); | ||
709 | |||
699 | struct sway_node *parent = node_get_parent(&c->node); | 710 | struct sway_node *parent = node_get_parent(&c->node); |
700 | struct wlr_box parent_box = {0, 0, 0, 0}; | 711 | struct wlr_box parent_box = {0, 0, 0, 0}; |
701 | 712 | ||
@@ -1086,10 +1097,6 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) { | |||
1086 | json_object_new_string(device->identifier)); | 1097 | json_object_new_string(device->identifier)); |
1087 | json_object_object_add(object, "name", | 1098 | json_object_object_add(object, "name", |
1088 | json_object_new_string(device->wlr_device->name)); | 1099 | json_object_new_string(device->wlr_device->name)); |
1089 | json_object_object_add(object, "vendor", | ||
1090 | json_object_new_int(device->wlr_device->vendor)); | ||
1091 | json_object_object_add(object, "product", | ||
1092 | json_object_new_int(device->wlr_device->product)); | ||
1093 | json_object_object_add(object, "type", | 1100 | json_object_object_add(object, "type", |
1094 | json_object_new_string( | 1101 | json_object_new_string( |
1095 | input_device_get_type(device))); | 1102 | input_device_get_type(device))); |
@@ -1143,6 +1150,10 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) { | |||
1143 | libinput_dev = wlr_libinput_get_device_handle(device->wlr_device); | 1150 | libinput_dev = wlr_libinput_get_device_handle(device->wlr_device); |
1144 | json_object_object_add(object, "libinput", | 1151 | json_object_object_add(object, "libinput", |
1145 | describe_libinput_device(libinput_dev)); | 1152 | describe_libinput_device(libinput_dev)); |
1153 | json_object_object_add(object, "vendor", | ||
1154 | json_object_new_int(libinput_device_get_id_vendor(libinput_dev))); | ||
1155 | json_object_object_add(object, "product", | ||
1156 | json_object_new_int(libinput_device_get_id_product(libinput_dev))); | ||
1146 | } | 1157 | } |
1147 | #endif | 1158 | #endif |
1148 | 1159 | ||
diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 9692a77f..7f353c0e 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c | |||
@@ -1,5 +1,4 @@ | |||
1 | // See https://i3wm.org/docs/ipc.html for protocol information | 1 | // See https://i3wm.org/docs/ipc.html for protocol information |
2 | #define _POSIX_C_SOURCE 200112L | ||
3 | #include <linux/input-event-codes.h> | 2 | #include <linux/input-event-codes.h> |
4 | #include <assert.h> | 3 | #include <assert.h> |
5 | #include <errno.h> | 4 | #include <errno.h> |
diff --git a/sway/lock.c b/sway/lock.c index 8ad9c3f6..289e8ca4 100644 --- a/sway/lock.c +++ b/sway/lock.c | |||
@@ -1,6 +1,6 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <wlr/types/wlr_scene.h> | 2 | #include <wlr/types/wlr_scene.h> |
3 | #include <wlr/types/wlr_session_lock_v1.h> | ||
4 | #include "log.h" | 4 | #include "log.h" |
5 | #include "sway/input/cursor.h" | 5 | #include "sway/input/cursor.h" |
6 | #include "sway/input/keyboard.h" | 6 | #include "sway/input/keyboard.h" |
diff --git a/sway/main.c b/sway/main.c index 73254dc2..1c4939aa 100644 --- a/sway/main.c +++ b/sway/main.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <getopt.h> | 1 | #include <getopt.h> |
3 | #include <pango/pangocairo.h> | 2 | #include <pango/pangocairo.h> |
4 | #include <signal.h> | 3 | #include <signal.h> |
diff --git a/sway/server.c b/sway/server.c index cc20e89d..d159dc9b 100644 --- a/sway/server.c +++ b/sway/server.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <stdbool.h> | 2 | #include <stdbool.h> |
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
@@ -8,24 +7,32 @@ | |||
8 | #include <wlr/backend/headless.h> | 7 | #include <wlr/backend/headless.h> |
9 | #include <wlr/backend/multi.h> | 8 | #include <wlr/backend/multi.h> |
10 | #include <wlr/config.h> | 9 | #include <wlr/config.h> |
10 | #include <wlr/render/allocator.h> | ||
11 | #include <wlr/render/wlr_renderer.h> | 11 | #include <wlr/render/wlr_renderer.h> |
12 | #include <wlr/types/wlr_compositor.h> | 12 | #include <wlr/types/wlr_compositor.h> |
13 | #include <wlr/types/wlr_content_type_v1.h> | 13 | #include <wlr/types/wlr_content_type_v1.h> |
14 | #include <wlr/types/wlr_cursor_shape_v1.h> | 14 | #include <wlr/types/wlr_cursor_shape_v1.h> |
15 | #include <wlr/types/wlr_data_control_v1.h> | 15 | #include <wlr/types/wlr_data_control_v1.h> |
16 | #include <wlr/types/wlr_data_device.h> | ||
16 | #include <wlr/types/wlr_drm.h> | 17 | #include <wlr/types/wlr_drm.h> |
17 | #include <wlr/types/wlr_export_dmabuf_v1.h> | 18 | #include <wlr/types/wlr_export_dmabuf_v1.h> |
19 | #include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h> | ||
20 | #include <wlr/types/wlr_foreign_toplevel_management_v1.h> | ||
18 | #include <wlr/types/wlr_fractional_scale_v1.h> | 21 | #include <wlr/types/wlr_fractional_scale_v1.h> |
19 | #include <wlr/types/wlr_gamma_control_v1.h> | 22 | #include <wlr/types/wlr_gamma_control_v1.h> |
20 | #include <wlr/types/wlr_idle_notify_v1.h> | 23 | #include <wlr/types/wlr_idle_notify_v1.h> |
21 | #include <wlr/types/wlr_layer_shell_v1.h> | 24 | #include <wlr/types/wlr_layer_shell_v1.h> |
22 | #include <wlr/types/wlr_linux_dmabuf_v1.h> | 25 | #include <wlr/types/wlr_linux_dmabuf_v1.h> |
26 | #include <wlr/types/wlr_output_management_v1.h> | ||
27 | #include <wlr/types/wlr_output_power_management_v1.h> | ||
23 | #include <wlr/types/wlr_pointer_constraints_v1.h> | 28 | #include <wlr/types/wlr_pointer_constraints_v1.h> |
29 | #include <wlr/types/wlr_presentation_time.h> | ||
24 | #include <wlr/types/wlr_primary_selection_v1.h> | 30 | #include <wlr/types/wlr_primary_selection_v1.h> |
25 | #include <wlr/types/wlr_relative_pointer_v1.h> | 31 | #include <wlr/types/wlr_relative_pointer_v1.h> |
26 | #include <wlr/types/wlr_screencopy_v1.h> | 32 | #include <wlr/types/wlr_screencopy_v1.h> |
27 | #include <wlr/types/wlr_security_context_v1.h> | 33 | #include <wlr/types/wlr_security_context_v1.h> |
28 | #include <wlr/types/wlr_server_decoration.h> | 34 | #include <wlr/types/wlr_server_decoration.h> |
35 | #include <wlr/types/wlr_session_lock_v1.h> | ||
29 | #include <wlr/types/wlr_single_pixel_buffer_v1.h> | 36 | #include <wlr/types/wlr_single_pixel_buffer_v1.h> |
30 | #include <wlr/types/wlr_subcompositor.h> | 37 | #include <wlr/types/wlr_subcompositor.h> |
31 | #include <wlr/types/wlr_tablet_v2.h> | 38 | #include <wlr/types/wlr_tablet_v2.h> |
@@ -58,8 +65,9 @@ | |||
58 | #include <wlr/types/wlr_drm_lease_v1.h> | 65 | #include <wlr/types/wlr_drm_lease_v1.h> |
59 | #endif | 66 | #endif |
60 | 67 | ||
61 | #define SWAY_XDG_SHELL_VERSION 2 | 68 | #define SWAY_XDG_SHELL_VERSION 5 |
62 | #define SWAY_LAYER_SHELL_VERSION 4 | 69 | #define SWAY_LAYER_SHELL_VERSION 4 |
70 | #define SWAY_FOREIGN_TOPLEVEL_LIST_VERSION 1 | ||
63 | 71 | ||
64 | bool allow_unsupported_gpu = false; | 72 | bool allow_unsupported_gpu = false; |
65 | 73 | ||
@@ -93,6 +101,7 @@ static bool is_privileged(const struct wl_global *global) { | |||
93 | global == server.output_manager_v1->global || | 101 | global == server.output_manager_v1->global || |
94 | global == server.output_power_manager_v1->global || | 102 | global == server.output_power_manager_v1->global || |
95 | global == server.input_method->global || | 103 | global == server.input_method->global || |
104 | global == server.foreign_toplevel_list->global || | ||
96 | global == server.foreign_toplevel_manager->global || | 105 | global == server.foreign_toplevel_manager->global || |
97 | global == server.data_control_manager_v1->global || | 106 | global == server.data_control_manager_v1->global || |
98 | global == server.screencopy_manager_v1->global || | 107 | global == server.screencopy_manager_v1->global || |
@@ -103,7 +112,8 @@ static bool is_privileged(const struct wl_global *global) { | |||
103 | global == server.session_lock.manager->global || | 112 | global == server.session_lock.manager->global || |
104 | global == server.input->keyboard_shortcuts_inhibit->global || | 113 | global == server.input->keyboard_shortcuts_inhibit->global || |
105 | global == server.input->virtual_keyboard->global || | 114 | global == server.input->virtual_keyboard->global || |
106 | global == server.input->virtual_pointer->global; | 115 | global == server.input->virtual_pointer->global || |
116 | global == server.input->transient_seat_manager->global; | ||
107 | } | 117 | } |
108 | 118 | ||
109 | static bool filter_global(const struct wl_client *client, | 119 | static bool filter_global(const struct wl_client *client, |
@@ -163,6 +173,45 @@ static void detect_proprietary(struct wlr_backend *backend, void *data) { | |||
163 | drmFreeVersion(version); | 173 | drmFreeVersion(version); |
164 | } | 174 | } |
165 | 175 | ||
176 | static void handle_renderer_lost(struct wl_listener *listener, void *data) { | ||
177 | struct sway_server *server = wl_container_of(listener, server, renderer_lost); | ||
178 | |||
179 | sway_log(SWAY_INFO, "Re-creating renderer after GPU reset"); | ||
180 | |||
181 | struct wlr_renderer *renderer = wlr_renderer_autocreate(server->backend); | ||
182 | if (renderer == NULL) { | ||
183 | sway_log(SWAY_ERROR, "Unable to create renderer"); | ||
184 | return; | ||
185 | } | ||
186 | |||
187 | struct wlr_allocator *allocator = | ||
188 | wlr_allocator_autocreate(server->backend, renderer); | ||
189 | if (allocator == NULL) { | ||
190 | sway_log(SWAY_ERROR, "Unable to create allocator"); | ||
191 | wlr_renderer_destroy(renderer); | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | struct wlr_renderer *old_renderer = server->renderer; | ||
196 | struct wlr_allocator *old_allocator = server->allocator; | ||
197 | server->renderer = renderer; | ||
198 | server->allocator = allocator; | ||
199 | |||
200 | wl_list_remove(&server->renderer_lost.link); | ||
201 | wl_signal_add(&server->renderer->events.lost, &server->renderer_lost); | ||
202 | |||
203 | wlr_compositor_set_renderer(server->compositor, renderer); | ||
204 | |||
205 | for (int i = 0; i < root->outputs->length; ++i) { | ||
206 | struct sway_output *output = root->outputs->items[i]; | ||
207 | wlr_output_init_render(output->wlr_output, | ||
208 | server->allocator, server->renderer); | ||
209 | } | ||
210 | |||
211 | wlr_allocator_destroy(old_allocator); | ||
212 | wlr_renderer_destroy(old_renderer); | ||
213 | } | ||
214 | |||
166 | bool server_init(struct sway_server *server) { | 215 | bool server_init(struct sway_server *server) { |
167 | sway_log(SWAY_DEBUG, "Initializing Wayland server"); | 216 | sway_log(SWAY_DEBUG, "Initializing Wayland server"); |
168 | server->wl_display = wl_display_create(); | 217 | server->wl_display = wl_display_create(); |
@@ -186,6 +235,9 @@ bool server_init(struct sway_server *server) { | |||
186 | return false; | 235 | return false; |
187 | } | 236 | } |
188 | 237 | ||
238 | server->renderer_lost.notify = handle_renderer_lost; | ||
239 | wl_signal_add(&server->renderer->events.lost, &server->renderer_lost); | ||
240 | |||
189 | wlr_renderer_init_wl_shm(server->renderer, server->wl_display); | 241 | wlr_renderer_init_wl_shm(server->renderer, server->wl_display); |
190 | 242 | ||
191 | if (wlr_renderer_get_dmabuf_texture_formats(server->renderer) != NULL) { | 243 | if (wlr_renderer_get_dmabuf_texture_formats(server->renderer) != NULL) { |
@@ -289,6 +341,8 @@ bool server_init(struct sway_server *server) { | |||
289 | &server->output_power_manager_set_mode); | 341 | &server->output_power_manager_set_mode); |
290 | server->input_method = wlr_input_method_manager_v2_create(server->wl_display); | 342 | server->input_method = wlr_input_method_manager_v2_create(server->wl_display); |
291 | server->text_input = wlr_text_input_manager_v3_create(server->wl_display); | 343 | server->text_input = wlr_text_input_manager_v3_create(server->wl_display); |
344 | server->foreign_toplevel_list = | ||
345 | wlr_ext_foreign_toplevel_list_v1_create(server->wl_display, SWAY_FOREIGN_TOPLEVEL_LIST_VERSION); | ||
292 | server->foreign_toplevel_manager = | 346 | server->foreign_toplevel_manager = |
293 | wlr_foreign_toplevel_manager_v1_create(server->wl_display); | 347 | wlr_foreign_toplevel_manager_v1_create(server->wl_display); |
294 | 348 | ||
@@ -388,6 +442,7 @@ void server_fini(struct sway_server *server) { | |||
388 | wlr_xwayland_destroy(server->xwayland.wlr_xwayland); | 442 | wlr_xwayland_destroy(server->xwayland.wlr_xwayland); |
389 | #endif | 443 | #endif |
390 | wl_display_destroy_clients(server->wl_display); | 444 | wl_display_destroy_clients(server->wl_display); |
445 | wlr_backend_destroy(server->backend); | ||
391 | wl_display_destroy(server->wl_display); | 446 | wl_display_destroy(server->wl_display); |
392 | list_free(server->dirty_nodes); | 447 | list_free(server->dirty_nodes); |
393 | } | 448 | } |
diff --git a/sway/sway-ipc.7.scd b/sway/sway-ipc.7.scd index f4a5ccff..c9895e52 100644 --- a/sway/sway-ipc.7.scd +++ b/sway/sway-ipc.7.scd | |||
@@ -376,6 +376,12 @@ node and will have the following properties: | |||
376 | : integer | 376 | : integer |
377 | : (Only containers and views) The fullscreen mode of the node. 0 means none, 1 means | 377 | : (Only containers and views) The fullscreen mode of the node. 0 means none, 1 means |
378 | full workspace, and 2 means global fullscreen | 378 | full workspace, and 2 means global fullscreen |
379 | |- floating | ||
380 | : string | ||
381 | : Floating state of container. Can be either "auto_off" or "user_on" | ||
382 | |- scratchpad_state | ||
383 | : string | ||
384 | : Whether the window is in the scratchpad. Can be either "none" or "fresh" | ||
379 | |- app_id | 385 | |- app_id |
380 | : string | 386 | : string |
381 | : (Only views) For an xdg-shell view, the name of the application, if set. | 387 | : (Only views) For an xdg-shell view, the name of the application, if set. |
diff --git a/sway/sway-output.5.scd b/sway/sway-output.5.scd index 028cb7ab..7d088d5d 100644 --- a/sway/sway-output.5.scd +++ b/sway/sway-output.5.scd | |||
@@ -72,13 +72,11 @@ must be separated by one space. For example: | |||
72 | 72 | ||
73 | *output* <name> scale <factor> | 73 | *output* <name> scale <factor> |
74 | Scales the specified output by the specified scale _factor_. An integer is | 74 | Scales the specified output by the specified scale _factor_. An integer is |
75 | recommended, but fractional values are also supported. If a fractional | 75 | recommended, but fractional values are also supported. You may be better |
76 | value are specified, be warned that it is not possible to faithfully | 76 | served by setting an integer scale factor and adjusting the font size of |
77 | represent the contents of your windows - they will be rendered at the next | 77 | your applications to taste. HiDPI isn't supported with Xwayland clients |
78 | highest integer scale factor and downscaled. You may be better served by | 78 | (windows will blur). A fractional scale may be slightly adjusted to match |
79 | setting an integer scale factor and adjusting the font size of your | 79 | requirements of the protocol. |
80 | applications to taste. HiDPI isn't supported with Xwayland clients (windows | ||
81 | will blur). | ||
82 | 80 | ||
83 | *output* <name> scale_filter linear|nearest|smart | 81 | *output* <name> scale_filter linear|nearest|smart |
84 | Indicates how to scale application buffers that are rendered at a scale | 82 | Indicates how to scale application buffers that are rendered at a scale |
diff --git a/sway/sway_text_node.c b/sway/sway_text_node.c index b9a77d94..5eba53ba 100644 --- a/sway/sway_text_node.c +++ b/sway/sway_text_node.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <drm_fourcc.h> | 1 | #include <drm_fourcc.h> |
3 | #include <stdio.h> | 2 | #include <stdio.h> |
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
@@ -58,11 +57,11 @@ struct text_buffer { | |||
58 | }; | 57 | }; |
59 | 58 | ||
60 | static int get_text_width(struct sway_text_node *props) { | 59 | static int get_text_width(struct sway_text_node *props) { |
60 | int width = props->width; | ||
61 | if (props->max_width) { | 61 | if (props->max_width) { |
62 | return MIN(props->max_width, props->width); | 62 | width = MIN(width, props->max_width); |
63 | } | 63 | } |
64 | 64 | return MAX(width, 0); | |
65 | return props->width; | ||
66 | } | 65 | } |
67 | 66 | ||
68 | static void update_source_box(struct text_buffer *buffer) { | 67 | static void update_source_box(struct text_buffer *buffer) { |
diff --git a/sway/swaynag.c b/sway/swaynag.c index 6031174d..bc5e23ea 100644 --- a/sway/swaynag.c +++ b/sway/swaynag.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <signal.h> | 1 | #include <signal.h> |
3 | #include <stdbool.h> | 2 | #include <stdbool.h> |
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c index af925d05..d4003fe6 100644 --- a/sway/tree/arrange.c +++ b/sway/tree/arrange.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <ctype.h> | 1 | #include <ctype.h> |
3 | #include <stdbool.h> | 2 | #include <stdbool.h> |
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
diff --git a/sway/tree/container.c b/sway/tree/container.c index 30cb97ba..9224b4fb 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -1,9 +1,9 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <drm_fourcc.h> | 2 | #include <drm_fourcc.h> |
4 | #include <stdint.h> | 3 | #include <stdint.h> |
5 | #include <stdlib.h> | 4 | #include <stdlib.h> |
6 | #include <wayland-server-core.h> | 5 | #include <wayland-server-core.h> |
6 | #include <wlr/types/wlr_foreign_toplevel_management_v1.h> | ||
7 | #include <wlr/types/wlr_linux_dmabuf_v1.h> | 7 | #include <wlr/types/wlr_linux_dmabuf_v1.h> |
8 | #include <wlr/types/wlr_output_layout.h> | 8 | #include <wlr/types/wlr_output_layout.h> |
9 | #include <wlr/types/wlr_subcompositor.h> | 9 | #include <wlr/types/wlr_subcompositor.h> |
diff --git a/sway/tree/node.c b/sway/tree/node.c index 213cf0a6..7aaf9762 100644 --- a/sway/tree/node.c +++ b/sway/tree/node.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/output.h" | 1 | #include "sway/output.h" |
3 | #include "sway/server.h" | 2 | #include "sway/server.h" |
4 | #include "sway/tree/container.h" | 3 | #include "sway/tree/container.h" |
diff --git a/sway/tree/output.c b/sway/tree/output.c index cd7bf0c2..2d11195e 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <ctype.h> | 2 | #include <ctype.h> |
4 | #include <string.h> | 3 | #include <string.h> |
diff --git a/sway/tree/root.c b/sway/tree/root.c index e9cea5e2..ae3c3cb2 100644 --- a/sway/tree/root.c +++ b/sway/tree/root.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdbool.h> | 1 | #include <stdbool.h> |
3 | #include <stdlib.h> | 2 | #include <stdlib.h> |
4 | #include <string.h> | 3 | #include <string.h> |
diff --git a/sway/tree/view.c b/sway/tree/view.c index d6984178..35b4b73f 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -1,9 +1,10 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdlib.h> | 1 | #include <stdlib.h> |
3 | #include <strings.h> | 2 | #include <strings.h> |
4 | #include <wayland-server-core.h> | 3 | #include <wayland-server-core.h> |
5 | #include <wlr/render/wlr_renderer.h> | 4 | #include <wlr/render/wlr_renderer.h> |
6 | #include <wlr/types/wlr_buffer.h> | 5 | #include <wlr/types/wlr_buffer.h> |
6 | #include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h> | ||
7 | #include <wlr/types/wlr_foreign_toplevel_management_v1.h> | ||
7 | #include <wlr/types/wlr_output_layout.h> | 8 | #include <wlr/types/wlr_output_layout.h> |
8 | #include <wlr/types/wlr_server_decoration.h> | 9 | #include <wlr/types/wlr_server_decoration.h> |
9 | #include <wlr/types/wlr_subcompositor.h> | 10 | #include <wlr/types/wlr_subcompositor.h> |
@@ -410,6 +411,12 @@ void view_request_activate(struct sway_view *view, struct sway_seat *seat) { | |||
410 | transaction_commit_dirty(); | 411 | transaction_commit_dirty(); |
411 | } | 412 | } |
412 | 413 | ||
414 | void view_request_urgent(struct sway_view *view) { | ||
415 | if (config->focus_on_window_activation != FOWA_NONE) { | ||
416 | view_set_urgent(view, true); | ||
417 | } | ||
418 | } | ||
419 | |||
413 | void view_set_csd_from_server(struct sway_view *view, bool enabled) { | 420 | void view_set_csd_from_server(struct sway_view *view, bool enabled) { |
414 | sway_log(SWAY_DEBUG, "Telling view %p to set CSD to %i", view, enabled); | 421 | sway_log(SWAY_DEBUG, "Telling view %p to set CSD to %i", view, enabled); |
415 | if (view->xdg_decoration) { | 422 | if (view->xdg_decoration) { |
@@ -582,6 +589,14 @@ static struct sway_workspace *select_workspace(struct sway_view *view) { | |||
582 | return NULL; | 589 | return NULL; |
583 | } | 590 | } |
584 | 591 | ||
592 | static void update_ext_foreign_toplevel(struct sway_view *view) { | ||
593 | struct wlr_ext_foreign_toplevel_handle_v1_state toplevel_state = { | ||
594 | .app_id = view_get_app_id(view), | ||
595 | .title = view_get_title(view), | ||
596 | }; | ||
597 | wlr_ext_foreign_toplevel_handle_v1_update_state(view->ext_foreign_toplevel, &toplevel_state); | ||
598 | } | ||
599 | |||
585 | static bool should_focus(struct sway_view *view) { | 600 | static bool should_focus(struct sway_view *view) { |
586 | struct sway_seat *seat = input_manager_current_seat(); | 601 | struct sway_seat *seat = input_manager_current_seat(); |
587 | struct sway_container *prev_con = seat_get_focused_container(seat); | 602 | struct sway_container *prev_con = seat_get_focused_container(seat); |
@@ -751,6 +766,13 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, | |||
751 | } | 766 | } |
752 | } | 767 | } |
753 | 768 | ||
769 | struct wlr_ext_foreign_toplevel_handle_v1_state foreign_toplevel_state = { | ||
770 | .app_id = view_get_app_id(view), | ||
771 | .title = view_get_title(view), | ||
772 | }; | ||
773 | view->ext_foreign_toplevel = | ||
774 | wlr_ext_foreign_toplevel_handle_v1_create(server.foreign_toplevel_list, &foreign_toplevel_state); | ||
775 | |||
754 | view->foreign_toplevel = | 776 | view->foreign_toplevel = |
755 | wlr_foreign_toplevel_handle_v1_create(server.foreign_toplevel_manager); | 777 | wlr_foreign_toplevel_handle_v1_create(server.foreign_toplevel_manager); |
756 | view->foreign_activate_request.notify = handle_foreign_activate_request; | 778 | view->foreign_activate_request.notify = handle_foreign_activate_request; |
@@ -828,6 +850,10 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, | |||
828 | input_manager_set_focus(&view->container->node); | 850 | input_manager_set_focus(&view->container->node); |
829 | } | 851 | } |
830 | 852 | ||
853 | if (view->ext_foreign_toplevel) { | ||
854 | update_ext_foreign_toplevel(view); | ||
855 | } | ||
856 | |||
831 | const char *app_id; | 857 | const char *app_id; |
832 | const char *class; | 858 | const char *class; |
833 | if ((app_id = view_get_app_id(view)) != NULL) { | 859 | if ((app_id = view_get_app_id(view)) != NULL) { |
@@ -847,6 +873,11 @@ void view_unmap(struct sway_view *view) { | |||
847 | view->urgent_timer = NULL; | 873 | view->urgent_timer = NULL; |
848 | } | 874 | } |
849 | 875 | ||
876 | if (view->ext_foreign_toplevel) { | ||
877 | wlr_ext_foreign_toplevel_handle_v1_destroy(view->ext_foreign_toplevel); | ||
878 | view->ext_foreign_toplevel = NULL; | ||
879 | } | ||
880 | |||
850 | if (view->foreign_toplevel) { | 881 | if (view->foreign_toplevel) { |
851 | wlr_foreign_toplevel_handle_v1_destroy(view->foreign_toplevel); | 882 | wlr_foreign_toplevel_handle_v1_destroy(view->foreign_toplevel); |
852 | view->foreign_toplevel = NULL; | 883 | view->foreign_toplevel = NULL; |
@@ -1014,6 +1045,18 @@ static size_t parse_title_format(struct sway_view *view, char *buffer) { | |||
1014 | return len; | 1045 | return len; |
1015 | } | 1046 | } |
1016 | 1047 | ||
1048 | void view_update_app_id(struct sway_view *view) { | ||
1049 | const char *app_id = view_get_app_id(view); | ||
1050 | |||
1051 | if (view->foreign_toplevel && app_id) { | ||
1052 | wlr_foreign_toplevel_handle_v1_set_app_id(view->foreign_toplevel, app_id); | ||
1053 | } | ||
1054 | |||
1055 | if (view->ext_foreign_toplevel) { | ||
1056 | update_ext_foreign_toplevel(view); | ||
1057 | } | ||
1058 | } | ||
1059 | |||
1017 | void view_update_title(struct sway_view *view, bool force) { | 1060 | void view_update_title(struct sway_view *view, bool force) { |
1018 | const char *title = view_get_title(view); | 1061 | const char *title = view_get_title(view); |
1019 | 1062 | ||
@@ -1060,6 +1103,10 @@ void view_update_title(struct sway_view *view, bool force) { | |||
1060 | if (view->foreign_toplevel && title) { | 1103 | if (view->foreign_toplevel && title) { |
1061 | wlr_foreign_toplevel_handle_v1_set_title(view->foreign_toplevel, title); | 1104 | wlr_foreign_toplevel_handle_v1_set_title(view->foreign_toplevel, title); |
1062 | } | 1105 | } |
1106 | |||
1107 | if (view->ext_foreign_toplevel) { | ||
1108 | update_ext_foreign_toplevel(view); | ||
1109 | } | ||
1063 | } | 1110 | } |
1064 | 1111 | ||
1065 | bool view_is_visible(struct sway_view *view) { | 1112 | bool view_is_visible(struct sway_view *view) { |
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 40d33435..a68dc927 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809 | ||
2 | #include <ctype.h> | 1 | #include <ctype.h> |
3 | #include <limits.h> | 2 | #include <limits.h> |
4 | #include <stdbool.h> | 3 | #include <stdbool.h> |
diff --git a/sway/xdg_activation_v1.c b/sway/xdg_activation_v1.c index c26ee19a..b7c80dd4 100644 --- a/sway/xdg_activation_v1.c +++ b/sway/xdg_activation_v1.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <wlr/types/wlr_xdg_activation_v1.h> | 1 | #include <wlr/types/wlr_xdg_activation_v1.h> |
2 | #include <wlr/types/wlr_xdg_shell.h> | ||
2 | #include "sway/desktop/launcher.h" | 3 | #include "sway/desktop/launcher.h" |
3 | #include "sway/tree/view.h" | 4 | #include "sway/tree/view.h" |
4 | #include "sway/tree/workspace.h" | 5 | #include "sway/tree/workspace.h" |
@@ -17,11 +18,15 @@ void xdg_activation_v1_handle_request_activate(struct wl_listener *listener, | |||
17 | return; | 18 | return; |
18 | } | 19 | } |
19 | 20 | ||
21 | struct launcher_ctx *ctx = event->token->data; | ||
22 | if (ctx == NULL) { | ||
23 | return; | ||
24 | } | ||
25 | |||
20 | if (!xdg_surface->surface->mapped) { | 26 | if (!xdg_surface->surface->mapped) { |
21 | // This is a startup notification. If we are tracking it, the data | 27 | // This is a startup notification. If we are tracking it, the data |
22 | // field is a launcher_ctx. | 28 | // field is a launcher_ctx. |
23 | struct launcher_ctx *ctx = event->token->data; | 29 | if (ctx->activated) { |
24 | if (!ctx || ctx->activated) { | ||
25 | // This ctx has already been activated and cannot be used again | 30 | // This ctx has already been activated and cannot be used again |
26 | // for a startup notification. It will be destroyed | 31 | // for a startup notification. It will be destroyed |
27 | return; | 32 | return; |
@@ -32,9 +37,19 @@ void xdg_activation_v1_handle_request_activate(struct wl_listener *listener, | |||
32 | return; | 37 | return; |
33 | } | 38 | } |
34 | 39 | ||
35 | struct wlr_seat *wlr_seat = event->token->seat; | 40 | // This is an activation request. If this context is internal we have ctx->seat. |
36 | struct sway_seat *seat = wlr_seat ? wlr_seat->data : NULL; | 41 | struct sway_seat *seat = ctx->seat; |
37 | view_request_activate(view, seat); | 42 | if (!seat) { |
43 | // Otherwise, use the seat indicated by the launcher client in set_serial | ||
44 | seat = ctx->token->seat ? ctx->token->seat->data : NULL; | ||
45 | } | ||
46 | |||
47 | if (seat && ctx->had_focused_surface) { | ||
48 | view_request_activate(view, seat); | ||
49 | } else { | ||
50 | // The token is valid, but cannot be used to activate a window | ||
51 | view_request_urgent(view); | ||
52 | } | ||
38 | } | 53 | } |
39 | 54 | ||
40 | void xdg_activation_v1_handle_new_token(struct wl_listener *listener, void *data) { | 55 | void xdg_activation_v1_handle_new_token(struct wl_listener *listener, void *data) { |