diff options
-rw-r--r-- | include/sway/commands.h | 1 | ||||
-rw-r--r-- | include/sway/config.h | 11 | ||||
-rw-r--r-- | include/sway/tree/view.h | 6 | ||||
-rw-r--r-- | meson.build | 12 | ||||
-rw-r--r-- | meson_options.txt | 11 | ||||
-rw-r--r-- | sway/commands.c | 1 | ||||
-rw-r--r-- | sway/commands/focus_on_window_activation.c | 25 | ||||
-rw-r--r-- | sway/config/output.c | 4 | ||||
-rw-r--r-- | sway/desktop/output.c | 6 | ||||
-rw-r--r-- | sway/desktop/render.c | 3 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 22 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/server.c | 2 | ||||
-rw-r--r-- | sway/tree/view.c | 23 |
14 files changed, 108 insertions, 20 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h index 8e91c158..b0b5ed0f 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h | |||
@@ -117,6 +117,7 @@ sway_cmd cmd_floating_modifier; | |||
117 | sway_cmd cmd_floating_scroll; | 117 | sway_cmd cmd_floating_scroll; |
118 | sway_cmd cmd_focus; | 118 | sway_cmd cmd_focus; |
119 | sway_cmd cmd_focus_follows_mouse; | 119 | sway_cmd cmd_focus_follows_mouse; |
120 | sway_cmd cmd_focus_on_window_activation; | ||
120 | sway_cmd cmd_focus_wrapping; | 121 | sway_cmd cmd_focus_wrapping; |
121 | sway_cmd cmd_font; | 122 | sway_cmd cmd_font; |
122 | sway_cmd cmd_for_window; | 123 | sway_cmd cmd_for_window; |
diff --git a/include/sway/config.h b/include/sway/config.h index 18d10faa..4ee8c3c2 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -58,6 +58,16 @@ struct sway_mouse_binding { | |||
58 | }; | 58 | }; |
59 | 59 | ||
60 | /** | 60 | /** |
61 | * Focus on window activation. | ||
62 | */ | ||
63 | enum sway_fowa { | ||
64 | FOWA_SMART, | ||
65 | FOWA_URGENT, | ||
66 | FOWA_FOCUS, | ||
67 | FOWA_NONE, | ||
68 | }; | ||
69 | |||
70 | /** | ||
61 | * A "mode" of keybindings created via the `mode` command. | 71 | * A "mode" of keybindings created via the `mode` command. |
62 | */ | 72 | */ |
63 | struct sway_mode { | 73 | struct sway_mode { |
@@ -340,6 +350,7 @@ struct sway_config { | |||
340 | size_t font_height; | 350 | size_t font_height; |
341 | bool pango_markup; | 351 | bool pango_markup; |
342 | size_t urgent_timeout; | 352 | size_t urgent_timeout; |
353 | enum sway_fowa focus_on_window_activation; | ||
343 | 354 | ||
344 | // Flags | 355 | // Flags |
345 | bool focus_follows_mouse; | 356 | bool focus_follows_mouse; |
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index f73ce571..382ab6b9 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -167,6 +167,7 @@ struct sway_xwayland_view { | |||
167 | struct wl_listener request_maximize; | 167 | struct wl_listener request_maximize; |
168 | struct wl_listener request_configure; | 168 | struct wl_listener request_configure; |
169 | struct wl_listener request_fullscreen; | 169 | struct wl_listener request_fullscreen; |
170 | struct wl_listener request_activate; | ||
170 | struct wl_listener set_title; | 171 | struct wl_listener set_title; |
171 | struct wl_listener set_class; | 172 | struct wl_listener set_class; |
172 | struct wl_listener set_window_type; | 173 | struct wl_listener set_window_type; |
@@ -259,6 +260,11 @@ void view_autoconfigure(struct sway_view *view); | |||
259 | 260 | ||
260 | void view_set_activated(struct sway_view *view, bool activated); | 261 | void view_set_activated(struct sway_view *view, bool activated); |
261 | 262 | ||
263 | /** | ||
264 | * Called when the view requests to be focused. | ||
265 | */ | ||
266 | void view_request_activate(struct sway_view *view); | ||
267 | |||
262 | void view_set_tiled(struct sway_view *view, bool tiled); | 268 | void view_set_tiled(struct sway_view *view, bool tiled); |
263 | 269 | ||
264 | void view_close(struct sway_view *view); | 270 | void view_close(struct sway_view *view); |
diff --git a/meson.build b/meson.build index d5b33e6b..eb5cba84 100644 --- a/meson.build +++ b/meson.build | |||
@@ -106,7 +106,7 @@ endif | |||
106 | 106 | ||
107 | add_project_arguments('-DSYSCONFDIR="/@0@"'.format(sysconfdir), language : 'c') | 107 | add_project_arguments('-DSYSCONFDIR="/@0@"'.format(sysconfdir), language : 'c') |
108 | 108 | ||
109 | version = get_option('sway_version') | 109 | version = get_option('sway-version') |
110 | if version != '' | 110 | if version != '' |
111 | version = '"@0@"'.format(version) | 111 | version = '"@0@"'.format(version) |
112 | else | 112 | else |
@@ -120,6 +120,8 @@ else | |||
120 | endif | 120 | endif |
121 | add_project_arguments('-DSWAY_VERSION=@0@'.format(version), language: 'c') | 121 | add_project_arguments('-DSWAY_VERSION=@0@'.format(version), language: 'c') |
122 | 122 | ||
123 | add_project_arguments('-D_LD_LIBRARY_PATH="@0@"'.format(get_option('ld-library-path')), language: 'c') | ||
124 | |||
123 | sway_inc = include_directories('include') | 125 | sway_inc = include_directories('include') |
124 | 126 | ||
125 | subdir('include') | 127 | subdir('include') |
@@ -168,7 +170,7 @@ install_data( | |||
168 | install_dir: datadir + '/wayland-sessions' | 170 | install_dir: datadir + '/wayland-sessions' |
169 | ) | 171 | ) |
170 | 172 | ||
171 | if (get_option('default_wallpaper')) | 173 | if (get_option('default-wallpaper')) |
172 | wallpaper_files = files( | 174 | wallpaper_files = files( |
173 | 'assets/Sway_Wallpaper_Blue_768x1024.png', | 175 | 'assets/Sway_Wallpaper_Blue_768x1024.png', |
174 | 'assets/Sway_Wallpaper_Blue_768x1024_Portrait.png', | 176 | 'assets/Sway_Wallpaper_Blue_768x1024_Portrait.png', |
@@ -184,7 +186,7 @@ if (get_option('default_wallpaper')) | |||
184 | install_data(wallpaper_files, install_dir: wallpaper_install_dir) | 186 | install_data(wallpaper_files, install_dir: wallpaper_install_dir) |
185 | endif | 187 | endif |
186 | 188 | ||
187 | if (get_option('zsh_completions')) | 189 | if (get_option('zsh-completions')) |
188 | zsh_files = files( | 190 | zsh_files = files( |
189 | 'completions/zsh/_sway', | 191 | 'completions/zsh/_sway', |
190 | 'completions/zsh/_swaylock', | 192 | 'completions/zsh/_swaylock', |
@@ -195,7 +197,7 @@ if (get_option('zsh_completions')) | |||
195 | install_data(zsh_files, install_dir: zsh_install_dir) | 197 | install_data(zsh_files, install_dir: zsh_install_dir) |
196 | endif | 198 | endif |
197 | 199 | ||
198 | if (get_option('bash_completions')) | 200 | if (get_option('bash-completions')) |
199 | bash_files = files( | 201 | bash_files = files( |
200 | 'completions/bash/sway', | 202 | 'completions/bash/sway', |
201 | 'completions/bash/swayidle', | 203 | 'completions/bash/swayidle', |
@@ -207,7 +209,7 @@ if (get_option('bash_completions')) | |||
207 | install_data(bash_files, install_dir: bash_install_dir) | 209 | install_data(bash_files, install_dir: bash_install_dir) |
208 | endif | 210 | endif |
209 | 211 | ||
210 | if (get_option('fish_completions')) | 212 | if (get_option('fish-completions')) |
211 | fish_files = files( | 213 | fish_files = files( |
212 | 'completions/fish/sway.fish', | 214 | 'completions/fish/sway.fish', |
213 | 'completions/fish/swaylock.fish', | 215 | 'completions/fish/swaylock.fish', |
diff --git a/meson_options.txt b/meson_options.txt index 5e54607f..50d646fd 100644 --- a/meson_options.txt +++ b/meson_options.txt | |||
@@ -1,6 +1,7 @@ | |||
1 | option('sway_version', type : 'string', description: 'The version string reported in `sway --version`.') | 1 | option('sway-version', type : 'string', description: 'The version string reported in `sway --version`.') |
2 | option('default_wallpaper', type: 'boolean', value: true, description: 'Install the default wallpaper.') | 2 | option('ld-library-path', type: 'string', value: '', description: 'The LD_LIBRARY_PATH environment variable.') |
3 | option('zsh_completions', type: 'boolean', value: true, description: 'Install zsh shell completions.') | 3 | option('default-wallpaper', type: 'boolean', value: true, description: 'Install the default wallpaper.') |
4 | option('bash_completions', type: 'boolean', value: true, description: 'Install bash shell completions.') | 4 | option('zsh-completions', type: 'boolean', value: true, description: 'Install zsh shell completions.') |
5 | option('fish_completions', type: 'boolean', value: true, description: 'Install fish shell completions.') | 5 | option('bash-completions', type: 'boolean', value: true, description: 'Install bash shell completions.') |
6 | option('fish-completions', type: 'boolean', value: true, description: 'Install fish shell completions.') | ||
6 | option('enable-xwayland', type: 'boolean', value: true, description: 'Enable support for X11 applications') | 7 | option('enable-xwayland', type: 'boolean', value: true, description: 'Enable support for X11 applications') |
diff --git a/sway/commands.c b/sway/commands.c index 13f5983e..359856cc 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -106,6 +106,7 @@ static struct cmd_handler handlers[] = { | |||
106 | { "floating_modifier", cmd_floating_modifier }, | 106 | { "floating_modifier", cmd_floating_modifier }, |
107 | { "focus", cmd_focus }, | 107 | { "focus", cmd_focus }, |
108 | { "focus_follows_mouse", cmd_focus_follows_mouse }, | 108 | { "focus_follows_mouse", cmd_focus_follows_mouse }, |
109 | { "focus_on_window_activation", cmd_focus_on_window_activation }, | ||
109 | { "focus_wrapping", cmd_focus_wrapping }, | 110 | { "focus_wrapping", cmd_focus_wrapping }, |
110 | { "font", cmd_font }, | 111 | { "font", cmd_font }, |
111 | { "for_window", cmd_for_window }, | 112 | { "for_window", cmd_for_window }, |
diff --git a/sway/commands/focus_on_window_activation.c b/sway/commands/focus_on_window_activation.c new file mode 100644 index 00000000..1fb07918 --- /dev/null +++ b/sway/commands/focus_on_window_activation.c | |||
@@ -0,0 +1,25 @@ | |||
1 | #include "sway/commands.h" | ||
2 | |||
3 | struct cmd_results *cmd_focus_on_window_activation(int argc, char **argv) { | ||
4 | struct cmd_results *error = NULL; | ||
5 | if ((error = checkarg(argc, "focus_on_window_activation", | ||
6 | EXPECTED_EQUAL_TO, 1))) { | ||
7 | return error; | ||
8 | } | ||
9 | |||
10 | if (strcmp(argv[0], "smart") == 0) { | ||
11 | config->focus_on_window_activation = FOWA_SMART; | ||
12 | } else if (strcmp(argv[0], "urgent") == 0) { | ||
13 | config->focus_on_window_activation = FOWA_URGENT; | ||
14 | } else if (strcmp(argv[0], "focus") == 0) { | ||
15 | config->focus_on_window_activation = FOWA_FOCUS; | ||
16 | } else if (strcmp(argv[0], "none") == 0) { | ||
17 | config->focus_on_window_activation = FOWA_NONE; | ||
18 | } else { | ||
19 | return cmd_results_new(CMD_INVALID, "focus_on_window_activation", | ||
20 | "Expected " | ||
21 | "'focus_on_window_activation smart|urgent|focus|none'"); | ||
22 | } | ||
23 | |||
24 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
25 | } | ||
diff --git a/sway/config/output.c b/sway/config/output.c index 16ec9339..65f09258 100644 --- a/sway/config/output.c +++ b/sway/config/output.c | |||
@@ -196,6 +196,10 @@ void apply_output_config(struct output_config *oc, struct sway_container *output | |||
196 | wlr_log(WLR_DEBUG, "Set %s mode to %dx%d (%f GHz)", oc->name, oc->width, | 196 | wlr_log(WLR_DEBUG, "Set %s mode to %dx%d (%f GHz)", oc->name, oc->width, |
197 | oc->height, oc->refresh_rate); | 197 | oc->height, oc->refresh_rate); |
198 | set_mode(wlr_output, oc->width, oc->height, oc->refresh_rate); | 198 | set_mode(wlr_output, oc->width, oc->height, oc->refresh_rate); |
199 | } else if (!wl_list_empty(&wlr_output->modes)) { | ||
200 | struct wlr_output_mode *mode = | ||
201 | wl_container_of(wlr_output->modes.prev, mode, link); | ||
202 | wlr_output_set_mode(wlr_output, mode); | ||
199 | } | 203 | } |
200 | if (oc && oc->scale > 0) { | 204 | if (oc && oc->scale > 0) { |
201 | wlr_log(WLR_DEBUG, "Set %s scale to %f", oc->name, oc->scale); | 205 | wlr_log(WLR_DEBUG, "Set %s scale to %f", oc->name, oc->scale); |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index c228979d..c30e52a1 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -559,12 +559,6 @@ void handle_new_output(struct wl_listener *listener, void *data) { | |||
559 | 559 | ||
560 | wl_list_insert(&root_container.sway_root->all_outputs, &output->link); | 560 | wl_list_insert(&root_container.sway_root->all_outputs, &output->link); |
561 | 561 | ||
562 | if (!wl_list_empty(&wlr_output->modes)) { | ||
563 | struct wlr_output_mode *mode = | ||
564 | wl_container_of(wlr_output->modes.prev, mode, link); | ||
565 | wlr_output_set_mode(wlr_output, mode); | ||
566 | } | ||
567 | |||
568 | output_enable(output); | 562 | output_enable(output); |
569 | } | 563 | } |
570 | 564 | ||
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 5556e5b3..695213eb 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -346,7 +346,8 @@ static void render_titlebar(struct sway_output *output, | |||
346 | float output_scale = output->wlr_output->scale; | 346 | float output_scale = output->wlr_output->scale; |
347 | enum sway_container_layout layout = state->parent->current.layout; | 347 | enum sway_container_layout layout = state->parent->current.layout; |
348 | list_t *children = state->parent->current.children; | 348 | list_t *children = state->parent->current.children; |
349 | bool is_last_child = children->items[children->length - 1] == con; | 349 | bool is_last_child = children->length == 0 || |
350 | children->items[children->length - 1] == con; | ||
350 | double output_x = output->swayc->current.swayc_x; | 351 | double output_x = output->swayc->current.swayc_x; |
351 | double output_y = output->swayc->current.swayc_y; | 352 | double output_y = output->swayc->current.swayc_y; |
352 | 353 | ||
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 2adc28c5..10faf91d 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -218,7 +218,9 @@ static bool wants_floating(struct sway_view *view) { | |||
218 | struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; | 218 | struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; |
219 | struct sway_xwayland *xwayland = &server.xwayland; | 219 | struct sway_xwayland *xwayland = &server.xwayland; |
220 | 220 | ||
221 | // TODO: return true if the NET_WM_STATE is MODAL | 221 | if (surface->modal) { |
222 | return true; | ||
223 | } | ||
222 | 224 | ||
223 | for (size_t i = 0; i < surface->window_type_len; ++i) { | 225 | for (size_t i = 0; i < surface->window_type_len; ++i) { |
224 | xcb_atom_t type = surface->window_type[i]; | 226 | xcb_atom_t type = surface->window_type[i]; |
@@ -335,6 +337,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { | |||
335 | wl_list_remove(&xwayland_view->request_fullscreen.link); | 337 | wl_list_remove(&xwayland_view->request_fullscreen.link); |
336 | wl_list_remove(&xwayland_view->request_move.link); | 338 | wl_list_remove(&xwayland_view->request_move.link); |
337 | wl_list_remove(&xwayland_view->request_resize.link); | 339 | wl_list_remove(&xwayland_view->request_resize.link); |
340 | wl_list_remove(&xwayland_view->request_activate.link); | ||
338 | wl_list_remove(&xwayland_view->set_title.link); | 341 | wl_list_remove(&xwayland_view->set_title.link); |
339 | wl_list_remove(&xwayland_view->set_class.link); | 342 | wl_list_remove(&xwayland_view->set_class.link); |
340 | wl_list_remove(&xwayland_view->set_window_type.link); | 343 | wl_list_remove(&xwayland_view->set_window_type.link); |
@@ -461,6 +464,19 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { | |||
461 | seat_begin_resize_floating(seat, view->swayc, seat->last_button, e->edges); | 464 | seat_begin_resize_floating(seat, view->swayc, seat->last_button, e->edges); |
462 | } | 465 | } |
463 | 466 | ||
467 | static void handle_request_activate(struct wl_listener *listener, void *data) { | ||
468 | struct sway_xwayland_view *xwayland_view = | ||
469 | wl_container_of(listener, xwayland_view, request_activate); | ||
470 | struct sway_view *view = &xwayland_view->view; | ||
471 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | ||
472 | if (!xsurface->mapped) { | ||
473 | return; | ||
474 | } | ||
475 | view_request_activate(view); | ||
476 | |||
477 | transaction_commit_dirty(); | ||
478 | } | ||
479 | |||
464 | static void handle_set_title(struct wl_listener *listener, void *data) { | 480 | static void handle_set_title(struct wl_listener *listener, void *data) { |
465 | struct sway_xwayland_view *xwayland_view = | 481 | struct sway_xwayland_view *xwayland_view = |
466 | wl_container_of(listener, xwayland_view, set_title); | 482 | wl_container_of(listener, xwayland_view, set_title); |
@@ -553,6 +569,10 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { | |||
553 | &xwayland_view->request_fullscreen); | 569 | &xwayland_view->request_fullscreen); |
554 | xwayland_view->request_fullscreen.notify = handle_request_fullscreen; | 570 | xwayland_view->request_fullscreen.notify = handle_request_fullscreen; |
555 | 571 | ||
572 | wl_signal_add(&xsurface->events.request_activate, | ||
573 | &xwayland_view->request_activate); | ||
574 | xwayland_view->request_activate.notify = handle_request_activate; | ||
575 | |||
556 | wl_signal_add(&xsurface->events.request_move, | 576 | wl_signal_add(&xsurface->events.request_move, |
557 | &xwayland_view->request_move); | 577 | &xwayland_view->request_move); |
558 | xwayland_view->request_move.notify = handle_request_move; | 578 | xwayland_view->request_move.notify = handle_request_move; |
diff --git a/sway/meson.build b/sway/meson.build index bcb44e8b..c14e58dd 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -46,6 +46,7 @@ sway_sources = files( | |||
46 | 'commands/floating_modifier.c', | 46 | 'commands/floating_modifier.c', |
47 | 'commands/focus.c', | 47 | 'commands/focus.c', |
48 | 'commands/focus_follows_mouse.c', | 48 | 'commands/focus_follows_mouse.c', |
49 | 'commands/focus_on_window_activation.c', | ||
49 | 'commands/focus_wrapping.c', | 50 | 'commands/focus_wrapping.c', |
50 | 'commands/font.c', | 51 | 'commands/font.c', |
51 | 'commands/for_window.c', | 52 | 'commands/for_window.c', |
diff --git a/sway/server.c b/sway/server.c index 7fa6007e..8b5bc93c 100644 --- a/sway/server.c +++ b/sway/server.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <wlr/types/wlr_gamma_control_v1.h> | 12 | #include <wlr/types/wlr_gamma_control_v1.h> |
13 | #include <wlr/types/wlr_idle.h> | 13 | #include <wlr/types/wlr_idle.h> |
14 | #include <wlr/types/wlr_layer_shell.h> | 14 | #include <wlr/types/wlr_layer_shell.h> |
15 | #include <wlr/types/wlr_linux_dmabuf_v1.h> | ||
16 | #include <wlr/types/wlr_primary_selection.h> | 15 | #include <wlr/types/wlr_primary_selection.h> |
17 | #include <wlr/types/wlr_screencopy_v1.h> | 16 | #include <wlr/types/wlr_screencopy_v1.h> |
18 | #include <wlr/types/wlr_server_decoration.h> | 17 | #include <wlr/types/wlr_server_decoration.h> |
@@ -117,7 +116,6 @@ bool server_init(struct sway_server *server) { | |||
117 | server->server_decoration.notify = handle_server_decoration; | 116 | server->server_decoration.notify = handle_server_decoration; |
118 | wl_list_init(&server->decorations); | 117 | wl_list_init(&server->decorations); |
119 | 118 | ||
120 | wlr_linux_dmabuf_v1_create(server->wl_display, renderer); | ||
121 | wlr_export_dmabuf_manager_v1_create(server->wl_display); | 119 | wlr_export_dmabuf_manager_v1_create(server->wl_display); |
122 | wlr_screencopy_manager_v1_create(server->wl_display); | 120 | wlr_screencopy_manager_v1_create(server->wl_display); |
123 | 121 | ||
diff --git a/sway/tree/view.c b/sway/tree/view.c index 1a98c5f2..6bd0ef67 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -280,6 +280,29 @@ void view_set_activated(struct sway_view *view, bool activated) { | |||
280 | } | 280 | } |
281 | } | 281 | } |
282 | 282 | ||
283 | void view_request_activate(struct sway_view *view) { | ||
284 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); | ||
285 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
286 | |||
287 | switch (config->focus_on_window_activation) { | ||
288 | case FOWA_SMART: | ||
289 | if (workspace_is_visible(ws)) { | ||
290 | seat_set_focus(seat, view->swayc); | ||
291 | } else { | ||
292 | view_set_urgent(view, true); | ||
293 | } | ||
294 | break; | ||
295 | case FOWA_URGENT: | ||
296 | view_set_urgent(view, true); | ||
297 | break; | ||
298 | case FOWA_FOCUS: | ||
299 | seat_set_focus(seat, view->swayc); | ||
300 | break; | ||
301 | case FOWA_NONE: | ||
302 | break; | ||
303 | } | ||
304 | } | ||
305 | |||
283 | void view_set_tiled(struct sway_view *view, bool tiled) { | 306 | void view_set_tiled(struct sway_view *view, bool tiled) { |
284 | if (!tiled) { | 307 | if (!tiled) { |
285 | view->using_csd = true; | 308 | view->using_csd = true; |